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