tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

regress_dns.c (72128B)


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