1 /* 2 * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> 3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include "../util-internal.h" 28 29 #ifdef _WIN32 30 #include <winsock2.h> 31 #include <windows.h> 32 #include <ws2tcpip.h> 33 #endif 34 35 #include "event2/event-config.h" 36 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #ifdef EVENT__HAVE_SYS_TIME_H 40 #include <sys/time.h> 41 #endif 42 #include <sys/queue.h> 43 #ifndef _WIN32 44 #include <sys/socket.h> 45 #include <signal.h> 46 #include <netinet/in.h> 47 #include <arpa/inet.h> 48 #include <unistd.h> 49 #endif 50 #ifdef EVENT__HAVE_NETINET_IN6_H 51 #include <netinet/in6.h> 52 #endif 53 #ifdef HAVE_NETDB_H 54 #include <netdb.h> 55 #endif 56 #include <fcntl.h> 57 #include <stdlib.h> 58 #include <stdio.h> 59 #include <string.h> 60 #include <errno.h> 61 62 #include "event2/dns.h" 63 #include "event2/dns_compat.h" 64 #include "event2/dns_struct.h" 65 #include "event2/event.h" 66 #include "event2/event_compat.h" 67 #include "event2/event_struct.h" 68 #include "event2/util.h" 69 #include "event2/listener.h" 70 #include "event2/bufferevent.h" 71 #include "log-internal.h" 72 #include "regress.h" 73 #include "regress_testutils.h" 74 75 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 76 77 static int dns_ok = 0; 78 static int dns_got_cancel = 0; 79 static int dns_err = 0; 80 81 82 static void 83 dns_gethostbyname_cb(int result, char type, int count, int ttl, 84 void *addresses, void *arg) 85 { 86 dns_ok = dns_err = 0; 87 88 if (result == DNS_ERR_TIMEOUT) { 89 printf("[Timed out] "); 90 dns_err = result; 91 goto out; 92 } 93 94 if (result != DNS_ERR_NONE) { 95 printf("[Error code %d] ", result); 96 goto out; 97 } 98 99 TT_BLATHER(("type: %d, count: %d, ttl: %d: ", type, count, ttl)); 100 101 switch (type) { 102 case DNS_IPv6_AAAA: { 103 #if defined(EVENT__HAVE_STRUCT_IN6_ADDR) && defined(EVENT__HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) 104 struct in6_addr *in6_addrs = addresses; 105 char buf[INET6_ADDRSTRLEN+1]; 106 int i; 107 /* a resolution that's not valid does not help */ 108 if (ttl < 0) 109 goto out; 110 for (i = 0; i < count; ++i) { 111 const char *b = evutil_inet_ntop(AF_INET6, &in6_addrs[i], buf,sizeof(buf)); 112 if (b) 113 TT_BLATHER(("%s ", b)); 114 else 115 TT_BLATHER(("%s ", strerror(errno))); 116 } 117 #endif 118 break; 119 } 120 case DNS_IPv4_A: { 121 struct in_addr *in_addrs = addresses; 122 int i; 123 /* a resolution that's not valid does not help */ 124 if (ttl < 0) 125 goto out; 126 for (i = 0; i < count; ++i) 127 TT_BLATHER(("%s ", inet_ntoa(in_addrs[i]))); 128 break; 129 } 130 case DNS_PTR: 131 /* may get at most one PTR */ 132 if (count != 1) 133 goto out; 134 135 TT_BLATHER(("%s ", *(char **)addresses)); 136 break; 137 default: 138 goto out; 139 } 140 141 dns_ok = type; 142 143 out: 144 if (arg == NULL) 145 event_loopexit(NULL); 146 else 147 event_base_loopexit((struct event_base *)arg, NULL); 148 } 149 150 static void 151 dns_gethostbyname(void) 152 { 153 dns_ok = 0; 154 evdns_resolve_ipv4("www.monkey.org", 0, dns_gethostbyname_cb, NULL); 155 event_dispatch(); 156 157 tt_int_op(dns_ok, ==, DNS_IPv4_A); 158 test_ok = dns_ok; 159 end: 160 ; 161 } 162 163 static void 164 dns_gethostbyname6(void) 165 { 166 dns_ok = 0; 167 evdns_resolve_ipv6("www.ietf.org", 0, dns_gethostbyname_cb, NULL); 168 event_dispatch(); 169 170 if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) { 171 tt_skip(); 172 } 173 174 tt_int_op(dns_ok, ==, DNS_IPv6_AAAA); 175 test_ok = 1; 176 end: 177 ; 178 } 179 180 static void 181 dns_gethostbyaddr(void) 182 { 183 struct in_addr in; 184 in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */ 185 dns_ok = 0; 186 evdns_resolve_reverse(&in, 0, dns_gethostbyname_cb, NULL); 187 event_dispatch(); 188 189 tt_int_op(dns_ok, ==, DNS_PTR); 190 test_ok = dns_ok; 191 end: 192 ; 193 } 194 195 static void 196 dns_resolve_reverse(void *ptr) 197 { 198 struct in_addr in; 199 struct event_base *base = event_base_new(); 200 struct evdns_base *dns = evdns_base_new(base, 1/* init name servers */); 201 struct evdns_request *req = NULL; 202 203 tt_assert(base); 204 tt_assert(dns); 205 in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */ 206 dns_ok = 0; 207 208 req = evdns_base_resolve_reverse( 209 dns, &in, 0, dns_gethostbyname_cb, base); 210 tt_assert(req); 211 212 event_base_dispatch(base); 213 214 tt_int_op(dns_ok, ==, DNS_PTR); 215 216 end: 217 if (dns) 218 evdns_base_free(dns, 0); 219 if (base) 220 event_base_free(base); 221 } 222 223 static int n_server_responses = 0; 224 225 static void 226 dns_server_request_cb(struct evdns_server_request *req, void *data) 227 { 228 int i, r; 229 const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa"; 230 const char TEST_IN6[] = 231 "f.e.f.e." "0.0.0.0." "0.0.0.0." "1.1.1.1." 232 "a.a.a.a." "0.0.0.0." "0.0.0.0." "0.f.f.f.ip6.arpa"; 233 234 for (i = 0; i < req->nquestions; ++i) { 235 const int qtype = req->questions[i]->type; 236 const int qclass = req->questions[i]->dns_question_class; 237 const char *qname = req->questions[i]->name; 238 239 struct in_addr ans; 240 ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ 241 if (qtype == EVDNS_TYPE_A && 242 qclass == EVDNS_CLASS_INET && 243 !evutil_ascii_strcasecmp(qname, "zz.example.com")) { 244 r = evdns_server_request_add_a_reply(req, qname, 245 1, &ans.s_addr, 12345); 246 if (r<0) 247 dns_ok = 0; 248 } else if (qtype == EVDNS_TYPE_AAAA && 249 qclass == EVDNS_CLASS_INET && 250 !evutil_ascii_strcasecmp(qname, "zz.example.com")) { 251 char addr6[17] = "abcdefghijklmnop"; 252 r = evdns_server_request_add_aaaa_reply(req, 253 qname, 1, addr6, 123); 254 if (r<0) 255 dns_ok = 0; 256 } else if (qtype == EVDNS_TYPE_PTR && 257 qclass == EVDNS_CLASS_INET && 258 !evutil_ascii_strcasecmp(qname, TEST_ARPA)) { 259 r = evdns_server_request_add_ptr_reply(req, NULL, 260 qname, "ZZ.EXAMPLE.COM", 54321); 261 if (r<0) 262 dns_ok = 0; 263 } else if (qtype == EVDNS_TYPE_PTR && 264 qclass == EVDNS_CLASS_INET && 265 !evutil_ascii_strcasecmp(qname, TEST_IN6)){ 266 r = evdns_server_request_add_ptr_reply(req, NULL, 267 qname, 268 "ZZ-INET6.EXAMPLE.COM", 54322); 269 if (r<0) 270 dns_ok = 0; 271 } else if (qtype == EVDNS_TYPE_A && 272 qclass == EVDNS_CLASS_INET && 273 !evutil_ascii_strcasecmp(qname, "drop.example.com")) { 274 if (evdns_server_request_drop(req)<0) 275 dns_ok = 0; 276 return; 277 } else { 278 printf("Unexpected question %d %d \"%s\" ", 279 qtype, qclass, qname); 280 dns_ok = 0; 281 } 282 } 283 r = evdns_server_request_respond(req, 0); 284 if (r<0) { 285 printf("Couldn't send reply. "); 286 dns_ok = 0; 287 } 288 } 289 290 static void 291 dns_server_gethostbyname_cb(int result, char type, int count, int ttl, 292 void *addresses, void *arg) 293 { 294 if (result == DNS_ERR_CANCEL) { 295 if (arg != (void*)(char*)90909) { 296 printf("Unexpected cancelation"); 297 dns_ok = 0; 298 } 299 dns_got_cancel = 1; 300 goto out; 301 } 302 if (result != DNS_ERR_NONE) { 303 printf("Unexpected result %d. ", result); 304 dns_ok = 0; 305 goto out; 306 } 307 if (count != 1) { 308 printf("Unexpected answer count %d. ", count); 309 dns_ok = 0; 310 goto out; 311 } 312 switch (type) { 313 case DNS_IPv4_A: { 314 struct in_addr *in_addrs = addresses; 315 if (in_addrs[0].s_addr != htonl(0xc0a80b0bUL) || ttl != 12345) { 316 printf("Bad IPv4 response \"%s\" %d. ", 317 inet_ntoa(in_addrs[0]), ttl); 318 dns_ok = 0; 319 goto out; 320 } 321 break; 322 } 323 case DNS_IPv6_AAAA: { 324 #if defined (EVENT__HAVE_STRUCT_IN6_ADDR) && defined(EVENT__HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) 325 struct in6_addr *in6_addrs = addresses; 326 char buf[INET6_ADDRSTRLEN+1]; 327 if (memcmp(&in6_addrs[0].s6_addr, "abcdefghijklmnop", 16) 328 || ttl != 123) { 329 const char *b = evutil_inet_ntop(AF_INET6, &in6_addrs[0],buf,sizeof(buf)); 330 printf("Bad IPv6 response \"%s\" %d. ", b, ttl); 331 dns_ok = 0; 332 goto out; 333 } 334 #endif 335 break; 336 } 337 case DNS_PTR: { 338 char **addrs = addresses; 339 if (arg != (void*)6) { 340 if (strcmp(addrs[0], "ZZ.EXAMPLE.COM") || 341 ttl != 54321) { 342 printf("Bad PTR response \"%s\" %d. ", 343 addrs[0], ttl); 344 dns_ok = 0; 345 goto out; 346 } 347 } else { 348 if (strcmp(addrs[0], "ZZ-INET6.EXAMPLE.COM") || 349 ttl != 54322) { 350 printf("Bad ipv6 PTR response \"%s\" %d. ", 351 addrs[0], ttl); 352 dns_ok = 0; 353 goto out; 354 } 355 } 356 break; 357 } 358 default: 359 printf("Bad response type %d. ", type); 360 dns_ok = 0; 361 } 362 out: 363 if (++n_server_responses == 3) { 364 event_loopexit(NULL); 365 } 366 } 367 368 static void 369 dns_server(void) 370 { 371 evutil_socket_t sock=-1; 372 struct sockaddr_in my_addr; 373 struct sockaddr_storage ss; 374 ev_socklen_t slen; 375 struct evdns_server_port *port=NULL; 376 struct in_addr resolve_addr; 377 struct in6_addr resolve_addr6; 378 struct evdns_base *base=NULL; 379 struct evdns_request *req=NULL; 380 381 dns_ok = 1; 382 383 base = evdns_base_new(NULL, 0); 384 385 /* Now configure a nameserver port. */ 386 sock = socket(AF_INET, SOCK_DGRAM, 0); 387 if (sock<0) { 388 tt_abort_perror("socket"); 389 } 390 391 evutil_make_socket_nonblocking(sock); 392 393 memset(&my_addr, 0, sizeof(my_addr)); 394 my_addr.sin_family = AF_INET; 395 my_addr.sin_port = 0; /* kernel picks */ 396 my_addr.sin_addr.s_addr = htonl(0x7f000001UL); 397 if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { 398 tt_abort_perror("bind"); 399 } 400 slen = sizeof(ss); 401 if (getsockname(sock, (struct sockaddr*)&ss, &slen) < 0) { 402 tt_abort_perror("getsockname"); 403 } 404 405 port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL); 406 407 /* Add ourself as the only nameserver, and make sure we really are 408 * the only nameserver. */ 409 evdns_base_nameserver_sockaddr_add(base, (struct sockaddr*)&ss, slen, 0); 410 tt_int_op(evdns_base_count_nameservers(base), ==, 1); 411 { 412 struct sockaddr_storage ss2; 413 int slen2; 414 415 memset(&ss2, 0, sizeof(ss2)); 416 417 slen2 = evdns_base_get_nameserver_addr(base, 0, (struct sockaddr *)&ss2, 3); 418 tt_int_op(slen2, ==, slen); 419 tt_int_op(ss2.ss_family, ==, 0); 420 slen2 = evdns_base_get_nameserver_addr(base, 0, (struct sockaddr *)&ss2, sizeof(ss2)); 421 tt_int_op(slen2, ==, slen); 422 tt_mem_op(&ss2, ==, &ss, slen); 423 424 slen2 = evdns_base_get_nameserver_addr(base, 1, (struct sockaddr *)&ss2, sizeof(ss2)); 425 tt_int_op(-1, ==, slen2); 426 } 427 428 /* Send some queries. */ 429 evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH, 430 dns_server_gethostbyname_cb, NULL); 431 evdns_base_resolve_ipv6(base, "zz.example.com", DNS_QUERY_NO_SEARCH, 432 dns_server_gethostbyname_cb, NULL); 433 resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ 434 evdns_base_resolve_reverse(base, &resolve_addr, 0, 435 dns_server_gethostbyname_cb, NULL); 436 memcpy(resolve_addr6.s6_addr, 437 "\xff\xf0\x00\x00\x00\x00\xaa\xaa" 438 "\x11\x11\x00\x00\x00\x00\xef\xef", 16); 439 evdns_base_resolve_reverse_ipv6(base, &resolve_addr6, 0, 440 dns_server_gethostbyname_cb, (void*)6); 441 442 req = evdns_base_resolve_ipv4(base, 443 "drop.example.com", DNS_QUERY_NO_SEARCH, 444 dns_server_gethostbyname_cb, (void*)(char*)90909); 445 446 evdns_cancel_request(base, req); 447 448 event_dispatch(); 449 450 tt_assert(dns_got_cancel); 451 test_ok = dns_ok; 452 453 end: 454 if (port) 455 evdns_close_server_port(port); 456 if (sock >= 0) 457 evutil_closesocket(sock); 458 if (base) 459 evdns_base_free(base, 0); 460 } 461 462 static int n_replies_left; 463 static struct event_base *exit_base; 464 static struct evdns_server_port *exit_port; 465 466 struct generic_dns_callback_result { 467 int result; 468 char type; 469 int count; 470 int ttl; 471 size_t addrs_len; 472 void *addrs; 473 char addrs_buf[256]; 474 }; 475 476 static void 477 generic_dns_callback(int result, char type, int count, int ttl, void *addresses, 478 void *arg) 479 { 480 size_t len; 481 struct generic_dns_callback_result *res = arg; 482 res->result = result; 483 res->type = type; 484 res->count = count; 485 res->ttl = ttl; 486 487 if (type == DNS_IPv4_A) 488 len = count * 4; 489 else if (type == DNS_IPv6_AAAA) 490 len = count * 16; 491 else if (type == DNS_PTR) 492 len = strlen(addresses)+1; 493 else { 494 res->addrs_len = len = 0; 495 res->addrs = NULL; 496 } 497 if (len) { 498 res->addrs_len = len; 499 if (len > 256) 500 len = 256; 501 memcpy(res->addrs_buf, addresses, len); 502 res->addrs = res->addrs_buf; 503 } 504 505 --n_replies_left; 506 if (n_replies_left == 0) { 507 if (exit_port) { 508 evdns_close_server_port(exit_port); 509 exit_port = NULL; 510 } else 511 event_base_loopexit(exit_base, NULL); 512 } 513 } 514 515 static struct regress_dns_server_table search_table[] = { 516 { "host.a.example.com", "err", "3", 0, 0 }, 517 { "host.b.example.com", "err", "3", 0, 0 }, 518 { "host.c.example.com", "A", "11.22.33.44", 0, 0 }, 519 { "host2.a.example.com", "err", "3", 0, 0 }, 520 { "host2.b.example.com", "A", "200.100.0.100", 0, 0 }, 521 { "host2.c.example.com", "err", "3", 0, 0 }, 522 { "hostn.a.example.com", "errsoa", "0", 0, 0 }, 523 { "hostn.b.example.com", "errsoa", "3", 0, 0 }, 524 { "hostn.c.example.com", "err", "0", 0, 0 }, 525 526 { "host", "err", "3", 0, 0 }, 527 { "host2", "err", "3", 0, 0 }, 528 { "*", "err", "3", 0, 0 }, 529 { NULL, NULL, NULL, 0, 0 } 530 }; 531 static void 532 dns_search_test_impl(void *arg, int lower) 533 { 534 struct regress_dns_server_table table[ARRAY_SIZE(search_table)]; 535 struct basic_test_data *data = arg; 536 struct event_base *base = data->base; 537 struct evdns_base *dns = NULL; 538 ev_uint16_t portnum = 0; 539 char buf[64]; 540 541 struct generic_dns_callback_result r[8]; 542 size_t i; 543 544 for (i = 0; i < ARRAY_SIZE(table); ++i) { 545 table[i] = search_table[i]; 546 table[i].lower = lower; 547 } 548 549 tt_assert(regress_dnsserver(base, &portnum, table)); 550 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 551 552 dns = evdns_base_new(base, 0); 553 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 554 555 evdns_base_search_add(dns, "a.example.com"); 556 evdns_base_search_add(dns, "b.example.com"); 557 evdns_base_search_add(dns, "c.example.com"); 558 559 n_replies_left = ARRAY_SIZE(r); 560 exit_base = base; 561 562 evdns_base_resolve_ipv4(dns, "host", 0, generic_dns_callback, &r[0]); 563 evdns_base_resolve_ipv4(dns, "host2", 0, generic_dns_callback, &r[1]); 564 evdns_base_resolve_ipv4(dns, "host", DNS_NO_SEARCH, generic_dns_callback, &r[2]); 565 evdns_base_resolve_ipv4(dns, "host2", DNS_NO_SEARCH, generic_dns_callback, &r[3]); 566 evdns_base_resolve_ipv4(dns, "host3", 0, generic_dns_callback, &r[4]); 567 evdns_base_resolve_ipv4(dns, "hostn.a.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[5]); 568 evdns_base_resolve_ipv4(dns, "hostn.b.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[6]); 569 evdns_base_resolve_ipv4(dns, "hostn.c.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[7]); 570 571 event_base_dispatch(base); 572 573 tt_int_op(r[0].type, ==, DNS_IPv4_A); 574 tt_int_op(r[0].count, ==, 1); 575 tt_int_op(((ev_uint32_t*)r[0].addrs)[0], ==, htonl(0x0b16212c)); 576 tt_int_op(r[1].type, ==, DNS_IPv4_A); 577 tt_int_op(r[1].count, ==, 1); 578 tt_int_op(((ev_uint32_t*)r[1].addrs)[0], ==, htonl(0xc8640064)); 579 tt_int_op(r[2].result, ==, DNS_ERR_NOTEXIST); 580 tt_int_op(r[3].result, ==, DNS_ERR_NOTEXIST); 581 tt_int_op(r[4].result, ==, DNS_ERR_NOTEXIST); 582 tt_int_op(r[5].result, ==, DNS_ERR_NODATA); 583 tt_int_op(r[5].ttl, ==, 42); 584 tt_int_op(r[6].result, ==, DNS_ERR_NOTEXIST); 585 tt_int_op(r[6].ttl, ==, 42); 586 tt_int_op(r[7].result, ==, DNS_ERR_NODATA); 587 tt_int_op(r[7].ttl, ==, 0); 588 589 end: 590 if (dns) 591 evdns_base_free(dns, 0); 592 593 regress_clean_dnsserver(); 594 } 595 static void 596 dns_search_empty_test(void *arg) 597 { 598 struct basic_test_data *data = arg; 599 struct event_base *base = data->base; 600 struct evdns_base *dns = NULL; 601 602 dns = evdns_base_new(base, 0); 603 604 evdns_base_search_add(dns, "whatever.example.com"); 605 606 n_replies_left = 1; 607 exit_base = base; 608 609 tt_ptr_op(evdns_base_resolve_ipv4(dns, "", 0, generic_dns_callback, NULL), ==, NULL); 610 611 end: 612 if (dns) 613 evdns_base_free(dns, 0); 614 } 615 static void 616 dns_search_test(void *arg) 617 { 618 return dns_search_test_impl(arg, 0); 619 } 620 static void 621 dns_search_lower_test(void *arg) 622 { 623 return dns_search_test_impl(arg, 1); 624 } 625 626 static int request_count = 0; 627 static struct evdns_request *current_req = NULL; 628 629 static void 630 search_cancel_server_cb(struct evdns_server_request *req, void *data) 631 { 632 const char *question; 633 634 if (req->nquestions != 1) 635 TT_DIE(("Only handling one question at a time; got %d", 636 req->nquestions)); 637 638 question = req->questions[0]->name; 639 640 TT_BLATHER(("got question, %s", question)); 641 642 tt_assert(request_count > 0); 643 tt_assert(!evdns_server_request_respond(req, 3)); 644 645 if (!--request_count) 646 evdns_cancel_request(NULL, current_req); 647 648 end: 649 ; 650 } 651 652 static void 653 dns_search_cancel_test(void *arg) 654 { 655 struct basic_test_data *data = arg; 656 struct event_base *base = data->base; 657 struct evdns_base *dns = NULL; 658 struct evdns_server_port *port = NULL; 659 ev_uint16_t portnum = 0; 660 struct generic_dns_callback_result r1; 661 char buf[64]; 662 663 port = regress_get_dnsserver(base, &portnum, NULL, 664 search_cancel_server_cb, NULL); 665 tt_assert(port); 666 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 667 668 dns = evdns_base_new(base, 0); 669 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 670 671 evdns_base_search_add(dns, "a.example.com"); 672 evdns_base_search_add(dns, "b.example.com"); 673 evdns_base_search_add(dns, "c.example.com"); 674 evdns_base_search_add(dns, "d.example.com"); 675 676 exit_base = base; 677 request_count = 3; 678 n_replies_left = 1; 679 680 current_req = evdns_base_resolve_ipv4(dns, "host", 0, 681 generic_dns_callback, &r1); 682 event_base_dispatch(base); 683 684 tt_int_op(r1.result, ==, DNS_ERR_CANCEL); 685 686 end: 687 if (port) 688 evdns_close_server_port(port); 689 if (dns) 690 evdns_base_free(dns, 0); 691 } 692 693 static void 694 fail_server_cb(struct evdns_server_request *req, void *data) 695 { 696 const char *question; 697 int *count = data; 698 struct in_addr in; 699 700 /* Drop the first N requests that we get. */ 701 if (*count > 0) { 702 --*count; 703 tt_want(! evdns_server_request_drop(req)); 704 return; 705 } 706 707 if (req->nquestions != 1) 708 TT_DIE(("Only handling one question at a time; got %d", 709 req->nquestions)); 710 711 question = req->questions[0]->name; 712 713 if (!evutil_ascii_strcasecmp(question, "google.com")) { 714 /* Detect a probe, and get out of the loop. */ 715 event_base_loopexit(exit_base, NULL); 716 } 717 718 tt_assert(evutil_inet_pton(AF_INET, "16.32.64.128", &in)); 719 evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, 720 100); 721 tt_assert(! evdns_server_request_respond(req, 0)) 722 return; 723 end: 724 tt_want(! evdns_server_request_drop(req)); 725 } 726 727 static void 728 dns_retry_test_impl(void *arg, int flags) 729 { 730 struct basic_test_data *data = arg; 731 struct event_base *base = data->base; 732 struct evdns_server_port *port = NULL; 733 struct evdns_base *dns = NULL; 734 int drop_count = 2; 735 ev_uint16_t portnum = 0; 736 char buf[64]; 737 738 struct generic_dns_callback_result r1; 739 740 port = regress_get_dnsserver(base, &portnum, NULL, 741 fail_server_cb, &drop_count); 742 tt_assert(port); 743 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 744 745 dns = evdns_base_new(base, flags); 746 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 747 tt_assert(! evdns_base_set_option(dns, "timeout", "0.2")); 748 tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "10")); 749 tt_assert(! evdns_base_set_option(dns, "initial-probe-timeout", "0.1")); 750 751 evdns_base_resolve_ipv4(dns, "host.example.com", 0, 752 generic_dns_callback, &r1); 753 754 n_replies_left = 1; 755 exit_base = base; 756 757 event_base_dispatch(base); 758 759 tt_int_op(drop_count, ==, 0); 760 761 tt_int_op(r1.type, ==, DNS_IPv4_A); 762 tt_int_op(r1.count, ==, 1); 763 tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x10204080)); 764 765 /* Now try again, but this time have the server get treated as 766 * failed, so we can send it a test probe. */ 767 drop_count = 4; 768 tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2")); 769 tt_assert(! evdns_base_set_option(dns, "attempts:", "3")); 770 memset(&r1, 0, sizeof(r1)); 771 772 evdns_base_resolve_ipv4(dns, "host.example.com", 0, 773 generic_dns_callback, &r1); 774 775 n_replies_left = 2; 776 777 /* This will run until it answers the "google.com" probe request. */ 778 event_base_dispatch(base); 779 780 /* We'll treat the server as failed here. */ 781 tt_int_op(r1.result, ==, DNS_ERR_TIMEOUT); 782 783 /* It should work this time. */ 784 tt_int_op(drop_count, ==, 0); 785 evdns_base_resolve_ipv4(dns, "host.example.com", 0, 786 generic_dns_callback, &r1); 787 788 event_base_dispatch(base); 789 tt_int_op(r1.result, ==, DNS_ERR_NONE); 790 tt_int_op(r1.type, ==, DNS_IPv4_A); 791 tt_int_op(r1.count, ==, 1); 792 tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x10204080)); 793 794 end: 795 if (dns) 796 evdns_base_free(dns, 0); 797 if (port) 798 evdns_close_server_port(port); 799 } 800 static void 801 dns_retry_test(void *arg) 802 { 803 dns_retry_test_impl(arg, 0); 804 } 805 static void 806 dns_retry_disable_when_inactive_test(void *arg) 807 { 808 dns_retry_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE); 809 } 810 811 static struct regress_dns_server_table internal_error_table[] = { 812 /* Error 4 (NOTIMPL) makes us reissue the request to another server 813 if we can. 814 815 XXXX we should reissue under a much wider set of circumstances! 816 */ 817 { "foof.example.com", "err", "4", 0, 0 }, 818 { NULL, NULL, NULL, 0, 0 } 819 }; 820 821 static struct regress_dns_server_table reissue_table[] = { 822 { "foof.example.com", "A", "240.15.240.15", 0, 0 }, 823 { NULL, NULL, NULL, 0, 0 } 824 }; 825 826 static void 827 dns_reissue_test_impl(void *arg, int flags) 828 { 829 struct basic_test_data *data = arg; 830 struct event_base *base = data->base; 831 struct evdns_server_port *port1 = NULL, *port2 = NULL; 832 struct evdns_base *dns = NULL; 833 struct generic_dns_callback_result r1; 834 ev_uint16_t portnum1 = 0, portnum2=0; 835 char buf1[64], buf2[64]; 836 837 port1 = regress_get_dnsserver(base, &portnum1, NULL, 838 regress_dns_server_cb, internal_error_table); 839 tt_assert(port1); 840 port2 = regress_get_dnsserver(base, &portnum2, NULL, 841 regress_dns_server_cb, reissue_table); 842 tt_assert(port2); 843 evutil_snprintf(buf1, sizeof(buf1), "127.0.0.1:%d", (int)portnum1); 844 evutil_snprintf(buf2, sizeof(buf2), "127.0.0.1:%d", (int)portnum2); 845 846 dns = evdns_base_new(base, flags); 847 tt_assert(!evdns_base_nameserver_ip_add(dns, buf1)); 848 tt_assert(! evdns_base_set_option(dns, "timeout:", "0.3")); 849 tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2")); 850 tt_assert(! evdns_base_set_option(dns, "attempts:", "5")); 851 852 memset(&r1, 0, sizeof(r1)); 853 evdns_base_resolve_ipv4(dns, "foof.example.com", 0, 854 generic_dns_callback, &r1); 855 856 /* Add this after, so that we are sure to get a reissue. */ 857 tt_assert(!evdns_base_nameserver_ip_add(dns, buf2)); 858 859 n_replies_left = 1; 860 exit_base = base; 861 862 event_base_dispatch(base); 863 tt_int_op(r1.result, ==, DNS_ERR_NONE); 864 tt_int_op(r1.type, ==, DNS_IPv4_A); 865 tt_int_op(r1.count, ==, 1); 866 tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0xf00ff00f)); 867 868 /* Make sure we dropped at least once. */ 869 tt_int_op(internal_error_table[0].seen, >, 0); 870 871 end: 872 if (dns) 873 evdns_base_free(dns, 0); 874 if (port1) 875 evdns_close_server_port(port1); 876 if (port2) 877 evdns_close_server_port(port2); 878 } 879 static void 880 dns_reissue_test(void *arg) 881 { 882 dns_reissue_test_impl(arg, 0); 883 } 884 static void 885 dns_reissue_disable_when_inactive_test(void *arg) 886 { 887 dns_reissue_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE); 888 } 889 890 #if 0 891 static void 892 dumb_bytes_fn(char *p, size_t n) 893 { 894 unsigned i; 895 /* This gets us 6 bits of entropy per transaction ID, which means we 896 * will have probably have collisions and need to pick again. */ 897 for (i=0;i<n;++i) 898 p[i] = (char)(rand() & 7); 899 } 900 #endif 901 902 static void 903 dns_inflight_test_impl(void *arg, int flags) 904 { 905 struct basic_test_data *data = arg; 906 struct event_base *base = data->base; 907 struct evdns_base *dns = NULL; 908 struct evdns_server_port *dns_port = NULL; 909 ev_uint16_t portnum = 0; 910 char buf[64]; 911 int disable_when_inactive = flags & EVDNS_BASE_DISABLE_WHEN_INACTIVE; 912 913 struct generic_dns_callback_result r[20]; 914 int i; 915 916 dns_port = regress_get_dnsserver(base, &portnum, NULL, 917 regress_dns_server_cb, reissue_table); 918 tt_assert(dns_port); 919 if (disable_when_inactive) { 920 exit_port = dns_port; 921 } 922 923 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 924 925 dns = evdns_base_new(base, flags); 926 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 927 tt_assert(! evdns_base_set_option(dns, "max-inflight:", "3")); 928 tt_assert(! evdns_base_set_option(dns, "randomize-case:", "0")); 929 930 for (i=0;i<20;++i) 931 evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r[i]); 932 933 n_replies_left = 20; 934 exit_base = base; 935 936 event_base_dispatch(base); 937 938 for (i=0;i<20;++i) { 939 tt_int_op(r[i].type, ==, DNS_IPv4_A); 940 tt_int_op(r[i].count, ==, 1); 941 tt_int_op(((ev_uint32_t*)r[i].addrs)[0], ==, htonl(0xf00ff00f)); 942 } 943 944 end: 945 if (dns) 946 evdns_base_free(dns, 0); 947 if (exit_port) { 948 evdns_close_server_port(exit_port); 949 exit_port = NULL; 950 } else if (! disable_when_inactive) { 951 evdns_close_server_port(dns_port); 952 } 953 } 954 955 static void 956 dns_inflight_test(void *arg) 957 { 958 dns_inflight_test_impl(arg, 0); 959 } 960 961 static void 962 dns_disable_when_inactive_test(void *arg) 963 { 964 dns_inflight_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE); 965 } 966 967 static void 968 dns_disable_when_inactive_no_ns_test(void *arg) 969 { 970 struct basic_test_data *data = arg; 971 struct event_base *base = data->base, *inactive_base; 972 struct evdns_base *dns = NULL; 973 ev_uint16_t portnum = 0; 974 char buf[64]; 975 struct generic_dns_callback_result r; 976 977 inactive_base = event_base_new(); 978 tt_assert(inactive_base); 979 980 /** Create dns server with inactive base, to avoid replying to clients */ 981 tt_assert(regress_dnsserver(inactive_base, &portnum, search_table)); 982 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 983 984 dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE); 985 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 986 tt_assert(! evdns_base_set_option(dns, "timeout:", "0.1")); 987 988 evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r); 989 n_replies_left = 1; 990 exit_base = base; 991 992 event_base_dispatch(base); 993 994 tt_int_op(n_replies_left, ==, 0); 995 996 tt_int_op(r.result, ==, DNS_ERR_TIMEOUT); 997 tt_int_op(r.count, ==, 0); 998 tt_ptr_op(r.addrs, ==, NULL); 999 1000 end: 1001 if (dns) 1002 evdns_base_free(dns, 0); 1003 regress_clean_dnsserver(); 1004 if (inactive_base) 1005 event_base_free(inactive_base); 1006 } 1007 1008 /* === Test for bufferevent_socket_connect_hostname */ 1009 1010 static int total_connected_or_failed = 0; 1011 static int total_n_accepted = 0; 1012 static struct event_base *be_connect_hostname_base = NULL; 1013 1014 /* Implements a DNS server for the connect_hostname test and the 1015 * getaddrinfo_async test */ 1016 static void 1017 be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data) 1018 { 1019 int i; 1020 int *n_got_p=data; 1021 int added_any=0; 1022 ++*n_got_p; 1023 1024 for (i=0;i<req->nquestions;++i) { 1025 const int qtype = req->questions[i]->type; 1026 const int qclass = req->questions[i]->dns_question_class; 1027 const char *qname = req->questions[i]->name; 1028 struct in_addr ans; 1029 struct in6_addr ans6; 1030 memset(&ans6, 0, sizeof(ans6)); 1031 1032 TT_BLATHER(("Got question about %s, type=%d", qname, qtype)); 1033 1034 if (qtype == EVDNS_TYPE_A && 1035 qclass == EVDNS_CLASS_INET && 1036 !evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) { 1037 ans.s_addr = htonl(0x7f000001); 1038 evdns_server_request_add_a_reply(req, qname, 1039 1, &ans.s_addr, 2000); 1040 added_any = 1; 1041 } else if (!evutil_ascii_strcasecmp(qname, 1042 "nosuchplace.example.com")) { 1043 /* ok, just say notfound. */ 1044 } else if (!evutil_ascii_strcasecmp(qname, 1045 "both.example.com")) { 1046 if (qtype == EVDNS_TYPE_A) { 1047 ans.s_addr = htonl(0x50502020); 1048 evdns_server_request_add_a_reply(req, qname, 1049 1, &ans.s_addr, 2000); 1050 added_any = 1; 1051 } else if (qtype == EVDNS_TYPE_AAAA) { 1052 ans6.s6_addr[0] = 0x80; 1053 ans6.s6_addr[1] = 0xff; 1054 ans6.s6_addr[14] = 0xbb; 1055 ans6.s6_addr[15] = 0xbb; 1056 evdns_server_request_add_aaaa_reply(req, qname, 1057 1, &ans6.s6_addr, 2000); 1058 added_any = 1; 1059 } 1060 evdns_server_request_add_cname_reply(req, qname, 1061 "both-canonical.example.com", 1000); 1062 } else if (!evutil_ascii_strcasecmp(qname, 1063 "v4only.example.com") || 1064 !evutil_ascii_strcasecmp(qname, "v4assert.example.com")) { 1065 if (qtype == EVDNS_TYPE_A) { 1066 ans.s_addr = htonl(0x12345678); 1067 evdns_server_request_add_a_reply(req, qname, 1068 1, &ans.s_addr, 2000); 1069 added_any = 1; 1070 } else if (!evutil_ascii_strcasecmp(qname, 1071 "v4assert.example.com")) { 1072 TT_FAIL(("Got an AAAA request for v4assert")); 1073 } 1074 } else if (!evutil_ascii_strcasecmp(qname, 1075 "v6only.example.com") || 1076 !evutil_ascii_strcasecmp(qname, "v6assert.example.com")) { 1077 if (qtype == EVDNS_TYPE_AAAA) { 1078 ans6.s6_addr[0] = 0x0b; 1079 ans6.s6_addr[1] = 0x0b; 1080 ans6.s6_addr[14] = 0xf0; 1081 ans6.s6_addr[15] = 0x0d; 1082 evdns_server_request_add_aaaa_reply(req, qname, 1083 1, &ans6.s6_addr, 2000); 1084 added_any = 1; 1085 } else if (!evutil_ascii_strcasecmp(qname, 1086 "v6assert.example.com")) { 1087 TT_FAIL(("Got a A request for v6assert")); 1088 } 1089 } else if (!evutil_ascii_strcasecmp(qname, 1090 "v6timeout.example.com")) { 1091 if (qtype == EVDNS_TYPE_A) { 1092 ans.s_addr = htonl(0xabcdef01); 1093 evdns_server_request_add_a_reply(req, qname, 1094 1, &ans.s_addr, 2000); 1095 added_any = 1; 1096 } else if (qtype == EVDNS_TYPE_AAAA) { 1097 /* Let the v6 request time out.*/ 1098 evdns_server_request_drop(req); 1099 return; 1100 } 1101 } else if (!evutil_ascii_strcasecmp(qname, 1102 "v4timeout.example.com")) { 1103 if (qtype == EVDNS_TYPE_AAAA) { 1104 ans6.s6_addr[0] = 0x0a; 1105 ans6.s6_addr[1] = 0x0a; 1106 ans6.s6_addr[14] = 0xff; 1107 ans6.s6_addr[15] = 0x01; 1108 evdns_server_request_add_aaaa_reply(req, qname, 1109 1, &ans6.s6_addr, 2000); 1110 added_any = 1; 1111 } else if (qtype == EVDNS_TYPE_A) { 1112 /* Let the v4 request time out.*/ 1113 evdns_server_request_drop(req); 1114 return; 1115 } 1116 } else if (!evutil_ascii_strcasecmp(qname, 1117 "v6timeout-nonexist.example.com")) { 1118 if (qtype == EVDNS_TYPE_A) { 1119 /* Fall through, give an nexist. */ 1120 } else if (qtype == EVDNS_TYPE_AAAA) { 1121 /* Let the v6 request time out.*/ 1122 evdns_server_request_drop(req); 1123 return; 1124 } 1125 } else if (!evutil_ascii_strcasecmp(qname, 1126 "all-timeout.example.com")) { 1127 /* drop all requests */ 1128 evdns_server_request_drop(req); 1129 return; 1130 } else { 1131 TT_GRIPE(("Got weird request for %s",qname)); 1132 } 1133 } 1134 if (added_any) { 1135 TT_BLATHER(("answering")); 1136 evdns_server_request_respond(req, 0); 1137 } else { 1138 TT_BLATHER(("saying nexist.")); 1139 evdns_server_request_respond(req, 3); 1140 } 1141 } 1142 1143 /* Implements a listener for connect_hostname test. */ 1144 static void 1145 nil_accept_cb(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *s, 1146 int socklen, void *arg) 1147 { 1148 int *p = arg; 1149 (*p)++; 1150 ++total_n_accepted; 1151 /* don't do anything with the socket; let it close when we exit() */ 1152 if (total_n_accepted >= 3 && total_connected_or_failed >= 5) 1153 event_base_loopexit(be_connect_hostname_base, 1154 NULL); 1155 } 1156 1157 struct be_conn_hostname_result { 1158 int dnserr; 1159 int what; 1160 }; 1161 1162 /* Bufferevent event callback for the connect_hostname test: remembers what 1163 * event we got. */ 1164 static void 1165 be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx) 1166 { 1167 struct be_conn_hostname_result *got = ctx; 1168 if (!got->what) { 1169 TT_BLATHER(("Got a bufferevent event %d", what)); 1170 got->what = what; 1171 1172 if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) { 1173 int r; 1174 if ((r = bufferevent_socket_get_dns_error(bev))) { 1175 got->dnserr = r; 1176 TT_BLATHER(("DNS error %d: %s", r, 1177 evutil_gai_strerror(r))); 1178 } ++total_connected_or_failed; 1179 TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed)); 1180 1181 if (total_n_accepted >= 3 && total_connected_or_failed >= 5) 1182 event_base_loopexit(be_connect_hostname_base, 1183 NULL); 1184 } 1185 } else { 1186 TT_FAIL(("Two events on one bufferevent. %d,%d", 1187 got->what, (int)what)); 1188 } 1189 } 1190 1191 static void 1192 test_bufferevent_connect_hostname(void *arg) 1193 { 1194 struct basic_test_data *data = arg; 1195 struct evconnlistener *listener = NULL; 1196 struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL; 1197 struct be_conn_hostname_result be1_outcome={0,0}, be2_outcome={0,0}, 1198 be3_outcome={0,0}, be4_outcome={0,0}, be5_outcome={0,0}; 1199 int expect_err5; 1200 struct evdns_base *dns=NULL; 1201 struct evdns_server_port *port=NULL; 1202 struct sockaddr_in sin; 1203 int listener_port=-1; 1204 ev_uint16_t dns_port=0; 1205 int n_accept=0, n_dns=0; 1206 char buf[128]; 1207 1208 be_connect_hostname_base = data->base; 1209 1210 /* Bind an address and figure out what port it's on. */ 1211 memset(&sin, 0, sizeof(sin)); 1212 sin.sin_family = AF_INET; 1213 sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ 1214 sin.sin_port = 0; 1215 listener = evconnlistener_new_bind(data->base, nil_accept_cb, 1216 &n_accept, 1217 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC, 1218 -1, (struct sockaddr *)&sin, sizeof(sin)); 1219 tt_assert(listener); 1220 listener_port = regress_get_socket_port( 1221 evconnlistener_get_fd(listener)); 1222 1223 port = regress_get_dnsserver(data->base, &dns_port, NULL, 1224 be_getaddrinfo_server_cb, &n_dns); 1225 tt_assert(port); 1226 tt_int_op(dns_port, >=, 0); 1227 1228 /* Start an evdns_base that uses the server as its resolver. */ 1229 dns = evdns_base_new(data->base, 0); 1230 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)dns_port); 1231 evdns_base_nameserver_ip_add(dns, buf); 1232 1233 /* Now, finally, at long last, launch the bufferevents. One should do 1234 * a failing lookup IP, one should do a successful lookup by IP, 1235 * and one should do a successful lookup by hostname. */ 1236 be1 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); 1237 be2 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); 1238 be3 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); 1239 be4 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); 1240 be5 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); 1241 1242 bufferevent_setcb(be1, NULL, NULL, be_connect_hostname_event_cb, 1243 &be1_outcome); 1244 bufferevent_setcb(be2, NULL, NULL, be_connect_hostname_event_cb, 1245 &be2_outcome); 1246 bufferevent_setcb(be3, NULL, NULL, be_connect_hostname_event_cb, 1247 &be3_outcome); 1248 bufferevent_setcb(be4, NULL, NULL, be_connect_hostname_event_cb, 1249 &be4_outcome); 1250 bufferevent_setcb(be5, NULL, NULL, be_connect_hostname_event_cb, 1251 &be5_outcome); 1252 1253 /* Use the blocking resolver. This one will fail if your resolver 1254 * can't resolve localhost to 127.0.0.1 */ 1255 tt_assert(!bufferevent_socket_connect_hostname(be4, NULL, AF_INET, 1256 "localhost", listener_port)); 1257 /* Use the blocking resolver with a nonexistent hostname. */ 1258 tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET, 1259 "nonesuch.nowhere.example.com", 80)); 1260 { 1261 /* The blocking resolver will use the system nameserver, which 1262 * might tell us anything. (Yes, some twits even pretend that 1263 * example.com is real.) Let's see what answer to expect. */ 1264 struct evutil_addrinfo hints, *ai = NULL; 1265 memset(&hints, 0, sizeof(hints)); 1266 hints.ai_family = AF_INET; 1267 hints.ai_socktype = SOCK_STREAM; 1268 hints.ai_protocol = IPPROTO_TCP; 1269 expect_err5 = evutil_getaddrinfo( 1270 "nonesuch.nowhere.example.com", "80", &hints, &ai); 1271 } 1272 /* Launch an async resolve that will fail. */ 1273 tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET, 1274 "nosuchplace.example.com", listener_port)); 1275 /* Connect to the IP without resolving. */ 1276 tt_assert(!bufferevent_socket_connect_hostname(be2, dns, AF_INET, 1277 "127.0.0.1", listener_port)); 1278 /* Launch an async resolve that will succeed. */ 1279 tt_assert(!bufferevent_socket_connect_hostname(be3, dns, AF_INET, 1280 "nobodaddy.example.com", listener_port)); 1281 1282 event_base_dispatch(data->base); 1283 1284 tt_int_op(be1_outcome.what, ==, BEV_EVENT_ERROR); 1285 tt_int_op(be1_outcome.dnserr, ==, EVUTIL_EAI_NONAME); 1286 tt_int_op(be2_outcome.what, ==, BEV_EVENT_CONNECTED); 1287 tt_int_op(be2_outcome.dnserr, ==, 0); 1288 tt_int_op(be3_outcome.what, ==, BEV_EVENT_CONNECTED); 1289 tt_int_op(be3_outcome.dnserr, ==, 0); 1290 tt_int_op(be4_outcome.what, ==, BEV_EVENT_CONNECTED); 1291 tt_int_op(be4_outcome.dnserr, ==, 0); 1292 if (expect_err5) { 1293 tt_int_op(be5_outcome.what, ==, BEV_EVENT_ERROR); 1294 tt_int_op(be5_outcome.dnserr, ==, expect_err5); 1295 } 1296 1297 tt_int_op(n_accept, ==, 3); 1298 tt_int_op(n_dns, ==, 2); 1299 1300 end: 1301 if (listener) 1302 evconnlistener_free(listener); 1303 if (port) 1304 evdns_close_server_port(port); 1305 if (dns) 1306 evdns_base_free(dns, 0); 1307 if (be1) 1308 bufferevent_free(be1); 1309 if (be2) 1310 bufferevent_free(be2); 1311 if (be3) 1312 bufferevent_free(be3); 1313 if (be4) 1314 bufferevent_free(be4); 1315 if (be5) 1316 bufferevent_free(be5); 1317 } 1318 1319 1320 struct gai_outcome { 1321 int err; 1322 struct evutil_addrinfo *ai; 1323 }; 1324 1325 static int n_gai_results_pending = 0; 1326 static struct event_base *exit_base_on_no_pending_results = NULL; 1327 1328 static void 1329 gai_cb(int err, struct evutil_addrinfo *res, void *ptr) 1330 { 1331 struct gai_outcome *go = ptr; 1332 go->err = err; 1333 go->ai = res; 1334 if (--n_gai_results_pending <= 0 && exit_base_on_no_pending_results) 1335 event_base_loopexit(exit_base_on_no_pending_results, NULL); 1336 if (n_gai_results_pending < 900) 1337 TT_BLATHER(("Got an answer; expecting %d more.", 1338 n_gai_results_pending)); 1339 } 1340 1341 static void 1342 cancel_gai_cb(evutil_socket_t fd, short what, void *ptr) 1343 { 1344 struct evdns_getaddrinfo_request *r = ptr; 1345 evdns_getaddrinfo_cancel(r); 1346 } 1347 1348 static void 1349 test_getaddrinfo_async(void *arg) 1350 { 1351 struct basic_test_data *data = arg; 1352 struct evutil_addrinfo hints, *a; 1353 struct gai_outcome local_outcome; 1354 struct gai_outcome a_out[12]; 1355 int i; 1356 struct evdns_getaddrinfo_request *r; 1357 char buf[128]; 1358 struct evdns_server_port *port = NULL; 1359 ev_uint16_t dns_port = 0; 1360 int n_dns_questions = 0; 1361 struct evdns_base *dns_base; 1362 1363 memset(a_out, 0, sizeof(a_out)); 1364 memset(&local_outcome, 0, sizeof(local_outcome)); 1365 1366 dns_base = evdns_base_new(data->base, 0); 1367 tt_assert(dns_base); 1368 1369 /* for localhost */ 1370 evdns_base_load_hosts(dns_base, NULL); 1371 1372 tt_assert(! evdns_base_set_option(dns_base, "timeout", "0.3")); 1373 tt_assert(! evdns_base_set_option(dns_base, "getaddrinfo-allow-skew", "0.2")); 1374 1375 n_gai_results_pending = 10000; /* don't think about exiting yet. */ 1376 1377 /* 1. Try some cases that will never hit the asynchronous resolver. */ 1378 /* 1a. Simple case with a symbolic service name */ 1379 memset(&hints, 0, sizeof(hints)); 1380 hints.ai_family = PF_UNSPEC; 1381 hints.ai_socktype = SOCK_STREAM; 1382 memset(&local_outcome, 0, sizeof(local_outcome)); 1383 r = evdns_getaddrinfo(dns_base, "1.2.3.4", "http", 1384 &hints, gai_cb, &local_outcome); 1385 tt_assert(! r); 1386 if (!local_outcome.err) { 1387 tt_ptr_op(local_outcome.ai,!=,NULL); 1388 test_ai_eq(local_outcome.ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP); 1389 evutil_freeaddrinfo(local_outcome.ai); 1390 local_outcome.ai = NULL; 1391 } else { 1392 TT_BLATHER(("Apparently we have no getservbyname.")); 1393 } 1394 1395 /* 1b. EVUTIL_AI_NUMERICHOST is set */ 1396 memset(&hints, 0, sizeof(hints)); 1397 hints.ai_family = PF_UNSPEC; 1398 hints.ai_flags = EVUTIL_AI_NUMERICHOST; 1399 memset(&local_outcome, 0, sizeof(local_outcome)); 1400 r = evdns_getaddrinfo(dns_base, "www.google.com", "80", 1401 &hints, gai_cb, &local_outcome); 1402 tt_ptr_op(r,==,NULL); 1403 tt_int_op(local_outcome.err,==,EVUTIL_EAI_NONAME); 1404 tt_ptr_op(local_outcome.ai,==,NULL); 1405 1406 /* 1c. We give a numeric address (ipv6) */ 1407 memset(&hints, 0, sizeof(hints)); 1408 memset(&local_outcome, 0, sizeof(local_outcome)); 1409 hints.ai_family = PF_UNSPEC; 1410 hints.ai_protocol = IPPROTO_TCP; 1411 r = evdns_getaddrinfo(dns_base, "f::f", "8008", 1412 &hints, gai_cb, &local_outcome); 1413 tt_assert(!r); 1414 tt_int_op(local_outcome.err,==,0); 1415 tt_assert(local_outcome.ai); 1416 tt_ptr_op(local_outcome.ai->ai_next,==,NULL); 1417 test_ai_eq(local_outcome.ai, "[f::f]:8008", SOCK_STREAM, IPPROTO_TCP); 1418 evutil_freeaddrinfo(local_outcome.ai); 1419 local_outcome.ai = NULL; 1420 1421 /* 1d. We give a numeric address (ipv4) */ 1422 memset(&hints, 0, sizeof(hints)); 1423 memset(&local_outcome, 0, sizeof(local_outcome)); 1424 hints.ai_family = PF_UNSPEC; 1425 r = evdns_getaddrinfo(dns_base, "5.6.7.8", NULL, 1426 &hints, gai_cb, &local_outcome); 1427 tt_assert(!r); 1428 tt_int_op(local_outcome.err,==,0); 1429 tt_assert(local_outcome.ai); 1430 a = ai_find_by_protocol(local_outcome.ai, IPPROTO_TCP); 1431 tt_assert(a); 1432 test_ai_eq(a, "5.6.7.8", SOCK_STREAM, IPPROTO_TCP); 1433 a = ai_find_by_protocol(local_outcome.ai, IPPROTO_UDP); 1434 tt_assert(a); 1435 test_ai_eq(a, "5.6.7.8", SOCK_DGRAM, IPPROTO_UDP); 1436 evutil_freeaddrinfo(local_outcome.ai); 1437 local_outcome.ai = NULL; 1438 1439 /* 1e. nodename is NULL (bind) */ 1440 memset(&hints, 0, sizeof(hints)); 1441 memset(&local_outcome, 0, sizeof(local_outcome)); 1442 hints.ai_family = PF_UNSPEC; 1443 hints.ai_socktype = SOCK_DGRAM; 1444 hints.ai_flags = EVUTIL_AI_PASSIVE; 1445 r = evdns_getaddrinfo(dns_base, NULL, "9090", 1446 &hints, gai_cb, &local_outcome); 1447 tt_assert(!r); 1448 tt_int_op(local_outcome.err,==,0); 1449 tt_assert(local_outcome.ai); 1450 /* we should get a v4 address of 0.0.0.0... */ 1451 a = ai_find_by_family(local_outcome.ai, PF_INET); 1452 tt_assert(a); 1453 test_ai_eq(a, "0.0.0.0:9090", SOCK_DGRAM, IPPROTO_UDP); 1454 /* ... and a v6 address of ::0 */ 1455 a = ai_find_by_family(local_outcome.ai, PF_INET6); 1456 tt_assert(a); 1457 test_ai_eq(a, "[::]:9090", SOCK_DGRAM, IPPROTO_UDP); 1458 evutil_freeaddrinfo(local_outcome.ai); 1459 local_outcome.ai = NULL; 1460 1461 /* 1f. nodename is NULL (connect) */ 1462 memset(&hints, 0, sizeof(hints)); 1463 memset(&local_outcome, 0, sizeof(local_outcome)); 1464 hints.ai_family = PF_UNSPEC; 1465 hints.ai_socktype = SOCK_STREAM; 1466 r = evdns_getaddrinfo(dns_base, NULL, "2", 1467 &hints, gai_cb, &local_outcome); 1468 tt_assert(!r); 1469 tt_int_op(local_outcome.err,==,0); 1470 tt_assert(local_outcome.ai); 1471 /* we should get a v4 address of 127.0.0.1 .... */ 1472 a = ai_find_by_family(local_outcome.ai, PF_INET); 1473 tt_assert(a); 1474 test_ai_eq(a, "127.0.0.1:2", SOCK_STREAM, IPPROTO_TCP); 1475 /* ... and a v6 address of ::1 */ 1476 a = ai_find_by_family(local_outcome.ai, PF_INET6); 1477 tt_assert(a); 1478 test_ai_eq(a, "[::1]:2", SOCK_STREAM, IPPROTO_TCP); 1479 evutil_freeaddrinfo(local_outcome.ai); 1480 local_outcome.ai = NULL; 1481 1482 /* 1g. We find localhost immediately. (pf_unspec) */ 1483 memset(&hints, 0, sizeof(hints)); 1484 memset(&local_outcome, 0, sizeof(local_outcome)); 1485 hints.ai_family = PF_UNSPEC; 1486 hints.ai_socktype = SOCK_STREAM; 1487 r = evdns_getaddrinfo(dns_base, "LOCALHOST", "80", 1488 &hints, gai_cb, &local_outcome); 1489 tt_assert(!r); 1490 tt_int_op(local_outcome.err,==,0); 1491 tt_assert(local_outcome.ai); 1492 /* we should get a v4 address of 127.0.0.1 .... */ 1493 a = ai_find_by_family(local_outcome.ai, PF_INET); 1494 tt_assert(a); 1495 test_ai_eq(a, "127.0.0.1:80", SOCK_STREAM, IPPROTO_TCP); 1496 /* ... and a v6 address of ::1 */ 1497 a = ai_find_by_family(local_outcome.ai, PF_INET6); 1498 tt_assert(a); 1499 test_ai_eq(a, "[::1]:80", SOCK_STREAM, IPPROTO_TCP); 1500 evutil_freeaddrinfo(local_outcome.ai); 1501 local_outcome.ai = NULL; 1502 1503 /* 1g. We find localhost immediately. (pf_inet6) */ 1504 memset(&hints, 0, sizeof(hints)); 1505 memset(&local_outcome, 0, sizeof(local_outcome)); 1506 hints.ai_family = PF_INET6; 1507 hints.ai_socktype = SOCK_STREAM; 1508 r = evdns_getaddrinfo(dns_base, "LOCALHOST", "9999", 1509 &hints, gai_cb, &local_outcome); 1510 tt_assert(! r); 1511 tt_int_op(local_outcome.err,==,0); 1512 tt_assert(local_outcome.ai); 1513 a = local_outcome.ai; 1514 test_ai_eq(a, "[::1]:9999", SOCK_STREAM, IPPROTO_TCP); 1515 tt_ptr_op(a->ai_next, ==, NULL); 1516 evutil_freeaddrinfo(local_outcome.ai); 1517 local_outcome.ai = NULL; 1518 1519 /* 2. Okay, now we can actually test the asynchronous resolver. */ 1520 /* Start a dummy local dns server... */ 1521 port = regress_get_dnsserver(data->base, &dns_port, NULL, 1522 be_getaddrinfo_server_cb, &n_dns_questions); 1523 tt_assert(port); 1524 tt_int_op(dns_port, >=, 0); 1525 /* ... and tell the evdns_base about it. */ 1526 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", dns_port); 1527 evdns_base_nameserver_ip_add(dns_base, buf); 1528 1529 memset(&hints, 0, sizeof(hints)); 1530 hints.ai_family = PF_UNSPEC; 1531 hints.ai_socktype = SOCK_STREAM; 1532 hints.ai_flags = EVUTIL_AI_CANONNAME; 1533 /* 0: Request for both.example.com should return both addresses. */ 1534 r = evdns_getaddrinfo(dns_base, "both.example.com", "8000", 1535 &hints, gai_cb, &a_out[0]); 1536 tt_assert(r); 1537 1538 /* 1: Request for v4only.example.com should return one address. */ 1539 r = evdns_getaddrinfo(dns_base, "v4only.example.com", "8001", 1540 &hints, gai_cb, &a_out[1]); 1541 tt_assert(r); 1542 1543 /* 2: Request for v6only.example.com should return one address. */ 1544 hints.ai_flags = 0; 1545 r = evdns_getaddrinfo(dns_base, "v6only.example.com", "8002", 1546 &hints, gai_cb, &a_out[2]); 1547 tt_assert(r); 1548 1549 /* 3: PF_INET request for v4assert.example.com should not generate a 1550 * v6 request. The server will fail the test if it does. */ 1551 hints.ai_family = PF_INET; 1552 r = evdns_getaddrinfo(dns_base, "v4assert.example.com", "8003", 1553 &hints, gai_cb, &a_out[3]); 1554 tt_assert(r); 1555 1556 /* 4: PF_INET6 request for v6assert.example.com should not generate a 1557 * v4 request. The server will fail the test if it does. */ 1558 hints.ai_family = PF_INET6; 1559 r = evdns_getaddrinfo(dns_base, "v6assert.example.com", "8004", 1560 &hints, gai_cb, &a_out[4]); 1561 tt_assert(r); 1562 1563 /* 5: PF_INET request for nosuchplace.example.com should give NEXIST. */ 1564 hints.ai_family = PF_INET; 1565 r = evdns_getaddrinfo(dns_base, "nosuchplace.example.com", "8005", 1566 &hints, gai_cb, &a_out[5]); 1567 tt_assert(r); 1568 1569 /* 6: PF_UNSPEC request for nosuchplace.example.com should give NEXIST. 1570 */ 1571 hints.ai_family = PF_UNSPEC; 1572 r = evdns_getaddrinfo(dns_base, "nosuchplace.example.com", "8006", 1573 &hints, gai_cb, &a_out[6]); 1574 tt_assert(r); 1575 1576 /* 7: PF_UNSPEC request for v6timeout.example.com should give an ipv4 1577 * address only. */ 1578 hints.ai_family = PF_UNSPEC; 1579 r = evdns_getaddrinfo(dns_base, "v6timeout.example.com", "8007", 1580 &hints, gai_cb, &a_out[7]); 1581 tt_assert(r); 1582 1583 /* 8: PF_UNSPEC request for v6timeout-nonexist.example.com should give 1584 * a NEXIST */ 1585 hints.ai_family = PF_UNSPEC; 1586 r = evdns_getaddrinfo(dns_base, "v6timeout-nonexist.example.com", 1587 "8008", &hints, gai_cb, &a_out[8]); 1588 tt_assert(r); 1589 1590 /* 9: AI_ADDRCONFIG should at least not crash. Can't test it more 1591 * without knowing what kind of internet we have. */ 1592 hints.ai_flags |= EVUTIL_AI_ADDRCONFIG; 1593 r = evdns_getaddrinfo(dns_base, "both.example.com", 1594 "8009", &hints, gai_cb, &a_out[9]); 1595 tt_assert(r); 1596 1597 /* 10: PF_UNSPEC for v4timeout.example.com should give an ipv6 address 1598 * only. */ 1599 hints.ai_family = PF_UNSPEC; 1600 hints.ai_flags = 0; 1601 r = evdns_getaddrinfo(dns_base, "v4timeout.example.com", "8010", 1602 &hints, gai_cb, &a_out[10]); 1603 tt_assert(r); 1604 1605 /* 11: timeout.example.com: cancel it after 100 msec. */ 1606 r = evdns_getaddrinfo(dns_base, "all-timeout.example.com", "8011", 1607 &hints, gai_cb, &a_out[11]); 1608 tt_assert(r); 1609 { 1610 struct timeval tv; 1611 tv.tv_sec = 0; 1612 tv.tv_usec = 100*1000; /* 100 msec */ 1613 event_base_once(data->base, -1, EV_TIMEOUT, cancel_gai_cb, 1614 r, &tv); 1615 } 1616 1617 /* XXXXX There are more tests we could do, including: 1618 1619 - A test to elicit NODATA. 1620 1621 */ 1622 1623 n_gai_results_pending = 12; 1624 exit_base_on_no_pending_results = data->base; 1625 1626 event_base_dispatch(data->base); 1627 1628 /* 0: both.example.com */ 1629 tt_int_op(a_out[0].err, ==, 0); 1630 tt_assert(a_out[0].ai); 1631 tt_assert(a_out[0].ai->ai_next); 1632 tt_assert(!a_out[0].ai->ai_next->ai_next); 1633 a = ai_find_by_family(a_out[0].ai, PF_INET); 1634 tt_assert(a); 1635 test_ai_eq(a, "80.80.32.32:8000", SOCK_STREAM, IPPROTO_TCP); 1636 a = ai_find_by_family(a_out[0].ai, PF_INET6); 1637 tt_assert(a); 1638 test_ai_eq(a, "[80ff::bbbb]:8000", SOCK_STREAM, IPPROTO_TCP); 1639 tt_assert(a_out[0].ai->ai_canonname); 1640 tt_str_op(a_out[0].ai->ai_canonname, ==, "both-canonical.example.com"); 1641 1642 /* 1: v4only.example.com */ 1643 tt_int_op(a_out[1].err, ==, 0); 1644 tt_assert(a_out[1].ai); 1645 tt_assert(! a_out[1].ai->ai_next); 1646 test_ai_eq(a_out[1].ai, "18.52.86.120:8001", SOCK_STREAM, IPPROTO_TCP); 1647 tt_assert(a_out[1].ai->ai_canonname == NULL); 1648 1649 1650 /* 2: v6only.example.com */ 1651 tt_int_op(a_out[2].err, ==, 0); 1652 tt_assert(a_out[2].ai); 1653 tt_assert(! a_out[2].ai->ai_next); 1654 test_ai_eq(a_out[2].ai, "[b0b::f00d]:8002", SOCK_STREAM, IPPROTO_TCP); 1655 1656 /* 3: v4assert.example.com */ 1657 tt_int_op(a_out[3].err, ==, 0); 1658 tt_assert(a_out[3].ai); 1659 tt_assert(! a_out[3].ai->ai_next); 1660 test_ai_eq(a_out[3].ai, "18.52.86.120:8003", SOCK_STREAM, IPPROTO_TCP); 1661 1662 /* 4: v6assert.example.com */ 1663 tt_int_op(a_out[4].err, ==, 0); 1664 tt_assert(a_out[4].ai); 1665 tt_assert(! a_out[4].ai->ai_next); 1666 test_ai_eq(a_out[4].ai, "[b0b::f00d]:8004", SOCK_STREAM, IPPROTO_TCP); 1667 1668 /* 5: nosuchplace.example.com (inet) */ 1669 tt_int_op(a_out[5].err, ==, EVUTIL_EAI_NONAME); 1670 tt_assert(! a_out[5].ai); 1671 1672 /* 6: nosuchplace.example.com (unspec) */ 1673 tt_int_op(a_out[6].err, ==, EVUTIL_EAI_NONAME); 1674 tt_assert(! a_out[6].ai); 1675 1676 /* 7: v6timeout.example.com */ 1677 tt_int_op(a_out[7].err, ==, 0); 1678 tt_assert(a_out[7].ai); 1679 tt_assert(! a_out[7].ai->ai_next); 1680 test_ai_eq(a_out[7].ai, "171.205.239.1:8007", SOCK_STREAM, IPPROTO_TCP); 1681 1682 /* 8: v6timeout-nonexist.example.com */ 1683 tt_int_op(a_out[8].err, ==, EVUTIL_EAI_NONAME); 1684 tt_assert(! a_out[8].ai); 1685 1686 /* 9: both (ADDRCONFIG) */ 1687 tt_int_op(a_out[9].err, ==, 0); 1688 tt_assert(a_out[9].ai); 1689 a = ai_find_by_family(a_out[9].ai, PF_INET); 1690 if (a) 1691 test_ai_eq(a, "80.80.32.32:8009", SOCK_STREAM, IPPROTO_TCP); 1692 else 1693 tt_assert(ai_find_by_family(a_out[9].ai, PF_INET6)); 1694 a = ai_find_by_family(a_out[9].ai, PF_INET6); 1695 if (a) 1696 test_ai_eq(a, "[80ff::bbbb]:8009", SOCK_STREAM, IPPROTO_TCP); 1697 else 1698 tt_assert(ai_find_by_family(a_out[9].ai, PF_INET)); 1699 1700 /* 10: v4timeout.example.com */ 1701 tt_int_op(a_out[10].err, ==, 0); 1702 tt_assert(a_out[10].ai); 1703 tt_assert(! a_out[10].ai->ai_next); 1704 test_ai_eq(a_out[10].ai, "[a0a::ff01]:8010", SOCK_STREAM, IPPROTO_TCP); 1705 1706 /* 11: cancelled request. */ 1707 tt_int_op(a_out[11].err, ==, EVUTIL_EAI_CANCEL); 1708 tt_assert(a_out[11].ai == NULL); 1709 1710 end: 1711 if (local_outcome.ai) 1712 evutil_freeaddrinfo(local_outcome.ai); 1713 for (i=0;i<(int)ARRAY_SIZE(a_out);++i) { 1714 if (a_out[i].ai) 1715 evutil_freeaddrinfo(a_out[i].ai); 1716 } 1717 if (port) 1718 evdns_close_server_port(port); 1719 if (dns_base) 1720 evdns_base_free(dns_base, 0); 1721 } 1722 1723 struct gaic_request_status { 1724 int magic; 1725 struct event_base *base; 1726 struct evdns_base *dns_base; 1727 struct evdns_getaddrinfo_request *request; 1728 struct event cancel_event; 1729 int canceled; 1730 }; 1731 1732 #define GAIC_MAGIC 0x1234abcd 1733 1734 static int pending = 0; 1735 1736 static void 1737 gaic_cancel_request_cb(evutil_socket_t fd, short what, void *arg) 1738 { 1739 struct gaic_request_status *status = arg; 1740 1741 tt_assert(status->magic == GAIC_MAGIC); 1742 status->canceled = 1; 1743 evdns_getaddrinfo_cancel(status->request); 1744 return; 1745 end: 1746 event_base_loopexit(status->base, NULL); 1747 } 1748 1749 static void 1750 gaic_server_cb(struct evdns_server_request *req, void *arg) 1751 { 1752 ev_uint32_t answer = 0x7f000001; 1753 tt_assert(req->nquestions); 1754 evdns_server_request_add_a_reply(req, req->questions[0]->name, 1, 1755 &answer, 100); 1756 evdns_server_request_respond(req, 0); 1757 return; 1758 end: 1759 evdns_server_request_respond(req, DNS_ERR_REFUSED); 1760 } 1761 1762 1763 static void 1764 gaic_getaddrinfo_cb(int result, struct evutil_addrinfo *res, void *arg) 1765 { 1766 struct gaic_request_status *status = arg; 1767 struct event_base *base = status->base; 1768 tt_assert(status->magic == GAIC_MAGIC); 1769 1770 if (result == EVUTIL_EAI_CANCEL) { 1771 tt_assert(status->canceled); 1772 } 1773 event_del(&status->cancel_event); 1774 1775 memset(status, 0xf0, sizeof(*status)); 1776 free(status); 1777 1778 end: 1779 if (--pending <= 0) 1780 event_base_loopexit(base, NULL); 1781 } 1782 1783 static void 1784 gaic_launch(struct event_base *base, struct evdns_base *dns_base) 1785 { 1786 struct gaic_request_status *status = calloc(1,sizeof(*status)); 1787 struct timeval tv = { 0, 10000 }; 1788 status->magic = GAIC_MAGIC; 1789 status->base = base; 1790 status->dns_base = dns_base; 1791 event_assign(&status->cancel_event, base, -1, 0, gaic_cancel_request_cb, 1792 status); 1793 status->request = evdns_getaddrinfo(dns_base, 1794 "foobar.bazquux.example.com", "80", NULL, gaic_getaddrinfo_cb, 1795 status); 1796 event_add(&status->cancel_event, &tv); 1797 ++pending; 1798 } 1799 1800 #ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED 1801 /* FIXME: We should move this to regress_main.c if anything else needs it.*/ 1802 1803 /* Trivial replacements for malloc/free/realloc to check for memory leaks. 1804 * Not threadsafe. */ 1805 static int allocated_chunks = 0; 1806 1807 static void * 1808 cnt_malloc(size_t sz) 1809 { 1810 allocated_chunks += 1; 1811 return malloc(sz); 1812 } 1813 1814 static void * 1815 cnt_realloc(void *old, size_t sz) 1816 { 1817 if (!old) 1818 allocated_chunks += 1; 1819 if (!sz) 1820 allocated_chunks -= 1; 1821 return realloc(old, sz); 1822 } 1823 1824 static void 1825 cnt_free(void *ptr) 1826 { 1827 allocated_chunks -= 1; 1828 free(ptr); 1829 } 1830 1831 struct testleak_env_t { 1832 struct event_base *base; 1833 struct evdns_base *dns_base; 1834 struct evdns_request *req; 1835 struct generic_dns_callback_result r; 1836 }; 1837 1838 static void * 1839 testleak_setup(const struct testcase_t *testcase) 1840 { 1841 struct testleak_env_t *env; 1842 1843 allocated_chunks = 0; 1844 1845 /* Reset allocation counter, to start allocations from the very beginning. 1846 * (this will avoid false-positive negative numbers for allocated_chunks) 1847 */ 1848 libevent_global_shutdown(); 1849 1850 event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free); 1851 1852 event_enable_debug_mode(); 1853 1854 /* not mm_calloc: we don't want to mess with the count. */ 1855 env = calloc(1, sizeof(struct testleak_env_t)); 1856 env->base = event_base_new(); 1857 env->dns_base = evdns_base_new(env->base, 0); 1858 env->req = evdns_base_resolve_ipv4( 1859 env->dns_base, "example.com", DNS_QUERY_NO_SEARCH, 1860 generic_dns_callback, &env->r); 1861 return env; 1862 } 1863 1864 static int 1865 testleak_cleanup(const struct testcase_t *testcase, void *env_) 1866 { 1867 int ok = 0; 1868 struct testleak_env_t *env = env_; 1869 tt_assert(env); 1870 #ifdef EVENT__DISABLE_DEBUG_MODE 1871 tt_int_op(allocated_chunks, ==, 0); 1872 #else 1873 libevent_global_shutdown(); 1874 tt_int_op(allocated_chunks, ==, 0); 1875 #endif 1876 ok = 1; 1877 end: 1878 if (env) { 1879 if (env->dns_base) 1880 evdns_base_free(env->dns_base, 0); 1881 if (env->base) 1882 event_base_free(env->base); 1883 free(env); 1884 } 1885 return ok; 1886 } 1887 1888 static struct testcase_setup_t testleak_funcs = { 1889 testleak_setup, testleak_cleanup 1890 }; 1891 1892 static void 1893 test_dbg_leak_cancel(void *env_) 1894 { 1895 /* cancel, loop, free/dns, free/base */ 1896 struct testleak_env_t *env = env_; 1897 int send_err_shutdown = 1; 1898 evdns_cancel_request(env->dns_base, env->req); 1899 env->req = 0; 1900 1901 /* `req` is freed in callback, that's why one loop is required. */ 1902 event_base_loop(env->base, EVLOOP_NONBLOCK); 1903 1904 /* send_err_shutdown means nothing as soon as our request is 1905 * already canceled */ 1906 evdns_base_free(env->dns_base, send_err_shutdown); 1907 env->dns_base = 0; 1908 event_base_free(env->base); 1909 env->base = 0; 1910 } 1911 1912 static void 1913 dbg_leak_resume(void *env_, int cancel, int send_err_shutdown) 1914 { 1915 /* cancel, loop, free/dns, free/base */ 1916 struct testleak_env_t *env = env_; 1917 if (cancel) { 1918 evdns_cancel_request(env->dns_base, env->req); 1919 tt_assert(!evdns_base_resume(env->dns_base)); 1920 } else { 1921 /* TODO: No nameservers, request can't be processed, must be errored */ 1922 tt_assert(!evdns_base_resume(env->dns_base)); 1923 } 1924 1925 event_base_loop(env->base, EVLOOP_NONBLOCK); 1926 /** 1927 * Because we don't cancel request, and want our callback to recieve 1928 * DNS_ERR_SHUTDOWN, we use deferred callback, and there was: 1929 * - one extra malloc(), 1930 * @see reply_schedule_callback() 1931 * - and one missing free 1932 * @see request_finished() (req->handle->pending_cb = 1) 1933 * than we don't need to count in testleak_cleanup(), but we can clean them 1934 * if we will run loop once again, but *after* evdns base freed. 1935 */ 1936 evdns_base_free(env->dns_base, send_err_shutdown); 1937 env->dns_base = 0; 1938 event_base_loop(env->base, EVLOOP_NONBLOCK); 1939 1940 end: 1941 event_base_free(env->base); 1942 env->base = 0; 1943 } 1944 1945 #define IMPL_DBG_LEAK_RESUME(name, cancel, send_err_shutdown) \ 1946 static void \ 1947 test_dbg_leak_##name##_(void *env_) \ 1948 { \ 1949 dbg_leak_resume(env_, cancel, send_err_shutdown); \ 1950 } 1951 IMPL_DBG_LEAK_RESUME(resume, 0, 0) 1952 IMPL_DBG_LEAK_RESUME(cancel_and_resume, 1, 0) 1953 IMPL_DBG_LEAK_RESUME(resume_send_err, 0, 1) 1954 IMPL_DBG_LEAK_RESUME(cancel_and_resume_send_err, 1, 1) 1955 1956 static void 1957 test_dbg_leak_shutdown(void *env_) 1958 { 1959 /* free/dns, loop, free/base */ 1960 struct testleak_env_t *env = env_; 1961 int send_err_shutdown = 1; 1962 1963 /* `req` is freed both with `send_err_shutdown` and without it, 1964 * the only difference is `evdns_callback` call */ 1965 env->req = 0; 1966 1967 evdns_base_free(env->dns_base, send_err_shutdown); 1968 env->dns_base = 0; 1969 1970 /* `req` is freed in callback, that's why one loop is required */ 1971 event_base_loop(env->base, EVLOOP_NONBLOCK); 1972 event_base_free(env->base); 1973 env->base = 0; 1974 } 1975 #endif 1976 1977 static void 1978 test_getaddrinfo_async_cancel_stress(void *ptr) 1979 { 1980 struct event_base *base; 1981 struct evdns_base *dns_base = NULL; 1982 struct evdns_server_port *server = NULL; 1983 evutil_socket_t fd = -1; 1984 struct sockaddr_in sin; 1985 struct sockaddr_storage ss; 1986 ev_socklen_t slen; 1987 int i; 1988 1989 base = event_base_new(); 1990 dns_base = evdns_base_new(base, 0); 1991 1992 memset(&sin, 0, sizeof(sin)); 1993 sin.sin_family = AF_INET; 1994 sin.sin_port = 0; 1995 sin.sin_addr.s_addr = htonl(0x7f000001); 1996 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1997 tt_abort_perror("socket"); 1998 } 1999 evutil_make_socket_nonblocking(fd); 2000 if (bind(fd, (struct sockaddr*)&sin, sizeof(sin))<0) { 2001 tt_abort_perror("bind"); 2002 } 2003 server = evdns_add_server_port_with_base(base, fd, 0, gaic_server_cb, 2004 base); 2005 2006 memset(&ss, 0, sizeof(ss)); 2007 slen = sizeof(ss); 2008 if (getsockname(fd, (struct sockaddr*)&ss, &slen)<0) { 2009 tt_abort_perror("getsockname"); 2010 } 2011 evdns_base_nameserver_sockaddr_add(dns_base, 2012 (struct sockaddr*)&ss, slen, 0); 2013 2014 for (i = 0; i < 1000; ++i) { 2015 gaic_launch(base, dns_base); 2016 } 2017 2018 event_base_dispatch(base); 2019 2020 end: 2021 if (dns_base) 2022 evdns_base_free(dns_base, 1); 2023 if (server) 2024 evdns_close_server_port(server); 2025 if (base) 2026 event_base_free(base); 2027 if (fd >= 0) 2028 evutil_closesocket(fd); 2029 } 2030 2031 static void 2032 dns_client_fail_requests_test(void *arg) 2033 { 2034 struct basic_test_data *data = arg; 2035 struct event_base *base = data->base; 2036 struct evdns_base *dns = NULL; 2037 struct evdns_server_port *dns_port = NULL; 2038 ev_uint16_t portnum = 0; 2039 char buf[64]; 2040 2041 struct generic_dns_callback_result r[20]; 2042 int i; 2043 2044 dns_port = regress_get_dnsserver(base, &portnum, NULL, 2045 regress_dns_server_cb, reissue_table); 2046 tt_assert(dns_port); 2047 2048 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 2049 2050 dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE); 2051 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 2052 2053 for (i = 0; i < 20; ++i) 2054 evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r[i]); 2055 2056 n_replies_left = 20; 2057 exit_base = base; 2058 2059 evdns_base_free(dns, 1 /** fail requests */); 2060 /** run defered callbacks, to trigger UAF */ 2061 event_base_dispatch(base); 2062 2063 tt_int_op(n_replies_left, ==, 0); 2064 for (i = 0; i < 20; ++i) 2065 tt_int_op(r[i].result, ==, DNS_ERR_SHUTDOWN); 2066 2067 end: 2068 evdns_close_server_port(dns_port); 2069 } 2070 2071 static void 2072 getaddrinfo_cb(int err, struct evutil_addrinfo *res, void *ptr) 2073 { 2074 generic_dns_callback(err, 0, 0, 0, NULL, ptr); 2075 } 2076 static void 2077 dns_client_fail_requests_getaddrinfo_test(void *arg) 2078 { 2079 struct basic_test_data *data = arg; 2080 struct event_base *base = data->base; 2081 struct evdns_base *dns = NULL; 2082 struct evdns_server_port *dns_port = NULL; 2083 ev_uint16_t portnum = 0; 2084 char buf[64]; 2085 2086 struct generic_dns_callback_result r[20]; 2087 int i; 2088 2089 dns_port = regress_get_dnsserver(base, &portnum, NULL, 2090 regress_dns_server_cb, reissue_table); 2091 tt_assert(dns_port); 2092 2093 evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); 2094 2095 dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE); 2096 tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); 2097 2098 for (i = 0; i < 20; ++i) 2099 tt_assert(evdns_getaddrinfo(dns, "foof.example.com", "ssh", NULL, getaddrinfo_cb, &r[i])); 2100 2101 n_replies_left = 20; 2102 exit_base = base; 2103 2104 evdns_base_free(dns, 1 /** fail requests */); 2105 /** run defered callbacks, to trigger UAF */ 2106 event_base_dispatch(base); 2107 2108 tt_int_op(n_replies_left, ==, 0); 2109 for (i = 0; i < 20; ++i) 2110 tt_int_op(r[i].result, ==, EVUTIL_EAI_FAIL); 2111 2112 end: 2113 evdns_close_server_port(dns_port); 2114 } 2115 2116 2117 #define DNS_LEGACY(name, flags) \ 2118 { #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \ 2119 dns_##name } 2120 2121 struct testcase_t dns_testcases[] = { 2122 DNS_LEGACY(server, TT_FORK|TT_NEED_BASE), 2123 DNS_LEGACY(gethostbyname, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT), 2124 DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT), 2125 DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT), 2126 { "resolve_reverse", dns_resolve_reverse, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL }, 2127 { "search_empty", dns_search_empty_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2128 { "search", dns_search_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2129 { "search_lower", dns_search_lower_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2130 { "search_cancel", dns_search_cancel_test, 2131 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2132 { "retry", dns_retry_test, TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, 2133 { "retry_disable_when_inactive", dns_retry_disable_when_inactive_test, 2134 TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, 2135 { "reissue", dns_reissue_test, TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, 2136 { "reissue_disable_when_inactive", dns_reissue_disable_when_inactive_test, 2137 TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, 2138 { "inflight", dns_inflight_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2139 { "bufferevent_connect_hostname", test_bufferevent_connect_hostname, 2140 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2141 { "disable_when_inactive", dns_disable_when_inactive_test, 2142 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2143 { "disable_when_inactive_no_ns", dns_disable_when_inactive_no_ns_test, 2144 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2145 2146 { "getaddrinfo_async", test_getaddrinfo_async, 2147 TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" }, 2148 { "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress, 2149 TT_FORK, NULL, NULL }, 2150 2151 #ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED 2152 { "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL }, 2153 { "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL }, 2154 2155 { "leak_resume", test_dbg_leak_resume_, TT_FORK, &testleak_funcs, NULL }, 2156 { "leak_cancel_and_resume", test_dbg_leak_cancel_and_resume_, 2157 TT_FORK, &testleak_funcs, NULL }, 2158 { "leak_resume_send_err", test_dbg_leak_resume_send_err_, 2159 TT_FORK, &testleak_funcs, NULL }, 2160 { "leak_cancel_and_resume_send_err", test_dbg_leak_cancel_and_resume_send_err_, 2161 TT_FORK, &testleak_funcs, NULL }, 2162 #endif 2163 2164 { "client_fail_requests", dns_client_fail_requests_test, 2165 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2166 { "client_fail_requests_getaddrinfo", 2167 dns_client_fail_requests_getaddrinfo_test, 2168 TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 2169 2170 END_OF_TESTCASES 2171 }; 2172 2173