ipc/chromium/src/third_party/libevent/test/regress_dns.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/third_party/libevent/test/regress_dns.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1855 @@
     1.4 +/*
     1.5 + * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
     1.6 + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
     1.7 + *
     1.8 + * Redistribution and use in source and binary forms, with or without
     1.9 + * modification, are permitted provided that the following conditions
    1.10 + * are met:
    1.11 + * 1. Redistributions of source code must retain the above copyright
    1.12 + *    notice, this list of conditions and the following disclaimer.
    1.13 + * 2. Redistributions in binary form must reproduce the above copyright
    1.14 + *    notice, this list of conditions and the following disclaimer in the
    1.15 + *    documentation and/or other materials provided with the distribution.
    1.16 + * 3. The name of the author may not be used to endorse or promote products
    1.17 + *    derived from this software without specific prior written permission.
    1.18 + *
    1.19 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    1.20 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    1.21 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    1.22 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    1.23 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.24 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.25 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.26 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.27 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    1.28 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.29 + */
    1.30 +
    1.31 +#ifdef WIN32
    1.32 +#include <winsock2.h>
    1.33 +#include <windows.h>
    1.34 +#include <ws2tcpip.h>
    1.35 +#endif
    1.36 +
    1.37 +#include "event2/event-config.h"
    1.38 +
    1.39 +#include <sys/types.h>
    1.40 +#include <sys/stat.h>
    1.41 +#ifdef _EVENT_HAVE_SYS_TIME_H
    1.42 +#include <sys/time.h>
    1.43 +#endif
    1.44 +#include <sys/queue.h>
    1.45 +#ifndef WIN32
    1.46 +#include <sys/socket.h>
    1.47 +#include <signal.h>
    1.48 +#include <netinet/in.h>
    1.49 +#include <arpa/inet.h>
    1.50 +#include <unistd.h>
    1.51 +#endif
    1.52 +#ifdef _EVENT_HAVE_NETINET_IN6_H
    1.53 +#include <netinet/in6.h>
    1.54 +#endif
    1.55 +#ifdef HAVE_NETDB_H
    1.56 +#include <netdb.h>
    1.57 +#endif
    1.58 +#include <fcntl.h>
    1.59 +#include <stdlib.h>
    1.60 +#include <stdio.h>
    1.61 +#include <string.h>
    1.62 +#include <errno.h>
    1.63 +
    1.64 +#include "event2/dns.h"
    1.65 +#include "event2/dns_compat.h"
    1.66 +#include "event2/dns_struct.h"
    1.67 +#include "event2/event.h"
    1.68 +#include "event2/event_compat.h"
    1.69 +#include "event2/event_struct.h"
    1.70 +#include "event2/util.h"
    1.71 +#include "event2/listener.h"
    1.72 +#include "event2/bufferevent.h"
    1.73 +#include "log-internal.h"
    1.74 +#include "regress.h"
    1.75 +#include "regress_testutils.h"
    1.76 +
    1.77 +#include "../util-internal.h"
    1.78 +
    1.79 +static int dns_ok = 0;
    1.80 +static int dns_got_cancel = 0;
    1.81 +static int dns_err = 0;
    1.82 +
    1.83 +
    1.84 +static void
    1.85 +dns_gethostbyname_cb(int result, char type, int count, int ttl,
    1.86 +    void *addresses, void *arg)
    1.87 +{
    1.88 +	dns_ok = dns_err = 0;
    1.89 +
    1.90 +	if (result == DNS_ERR_TIMEOUT) {
    1.91 +		printf("[Timed out] ");
    1.92 +		dns_err = result;
    1.93 +		goto out;
    1.94 +	}
    1.95 +
    1.96 +	if (result != DNS_ERR_NONE) {
    1.97 +		printf("[Error code %d] ", result);
    1.98 +		goto out;
    1.99 +	}
   1.100 +
   1.101 +	TT_BLATHER(("type: %d, count: %d, ttl: %d: ", type, count, ttl));
   1.102 +
   1.103 +	switch (type) {
   1.104 +	case DNS_IPv6_AAAA: {
   1.105 +#if defined(_EVENT_HAVE_STRUCT_IN6_ADDR) && defined(_EVENT_HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
   1.106 +		struct in6_addr *in6_addrs = addresses;
   1.107 +		char buf[INET6_ADDRSTRLEN+1];
   1.108 +		int i;
   1.109 +		/* a resolution that's not valid does not help */
   1.110 +		if (ttl < 0)
   1.111 +			goto out;
   1.112 +		for (i = 0; i < count; ++i) {
   1.113 +			const char *b = evutil_inet_ntop(AF_INET6, &in6_addrs[i], buf,sizeof(buf));
   1.114 +			if (b)
   1.115 +				TT_BLATHER(("%s ", b));
   1.116 +			else
   1.117 +				TT_BLATHER(("%s ", strerror(errno)));
   1.118 +		}
   1.119 +#endif
   1.120 +		break;
   1.121 +	}
   1.122 +	case DNS_IPv4_A: {
   1.123 +		struct in_addr *in_addrs = addresses;
   1.124 +		int i;
   1.125 +		/* a resolution that's not valid does not help */
   1.126 +		if (ttl < 0)
   1.127 +			goto out;
   1.128 +		for (i = 0; i < count; ++i)
   1.129 +			TT_BLATHER(("%s ", inet_ntoa(in_addrs[i])));
   1.130 +		break;
   1.131 +	}
   1.132 +	case DNS_PTR:
   1.133 +		/* may get at most one PTR */
   1.134 +		if (count != 1)
   1.135 +			goto out;
   1.136 +
   1.137 +		TT_BLATHER(("%s ", *(char **)addresses));
   1.138 +		break;
   1.139 +	default:
   1.140 +		goto out;
   1.141 +	}
   1.142 +
   1.143 +	dns_ok = type;
   1.144 +
   1.145 +out:
   1.146 +	if (arg == NULL)
   1.147 +		event_loopexit(NULL);
   1.148 +	else
   1.149 +		event_base_loopexit((struct event_base *)arg, NULL);
   1.150 +}
   1.151 +
   1.152 +static void
   1.153 +dns_gethostbyname(void)
   1.154 +{
   1.155 +	dns_ok = 0;
   1.156 +	evdns_resolve_ipv4("www.monkey.org", 0, dns_gethostbyname_cb, NULL);
   1.157 +	event_dispatch();
   1.158 +
   1.159 +	tt_int_op(dns_ok, ==, DNS_IPv4_A);
   1.160 +	test_ok = dns_ok;
   1.161 +end:
   1.162 +	;
   1.163 +}
   1.164 +
   1.165 +static void
   1.166 +dns_gethostbyname6(void)
   1.167 +{
   1.168 +	dns_ok = 0;
   1.169 +	evdns_resolve_ipv6("www.ietf.org", 0, dns_gethostbyname_cb, NULL);
   1.170 +	event_dispatch();
   1.171 +
   1.172 +	if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) {
   1.173 +		tt_skip();
   1.174 +	}
   1.175 +
   1.176 +	tt_int_op(dns_ok, ==, DNS_IPv6_AAAA);
   1.177 +	test_ok = 1;
   1.178 +end:
   1.179 +	;
   1.180 +}
   1.181 +
   1.182 +static void
   1.183 +dns_gethostbyaddr(void)
   1.184 +{
   1.185 +	struct in_addr in;
   1.186 +	in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */
   1.187 +	dns_ok = 0;
   1.188 +	evdns_resolve_reverse(&in, 0, dns_gethostbyname_cb, NULL);
   1.189 +	event_dispatch();
   1.190 +
   1.191 +	tt_int_op(dns_ok, ==, DNS_PTR);
   1.192 +	test_ok = dns_ok;
   1.193 +end:
   1.194 +	;
   1.195 +}
   1.196 +
   1.197 +static void
   1.198 +dns_resolve_reverse(void *ptr)
   1.199 +{
   1.200 +	struct in_addr in;
   1.201 +	struct event_base *base = event_base_new();
   1.202 +	struct evdns_base *dns = evdns_base_new(base, 1/* init name servers */);
   1.203 +	struct evdns_request *req = NULL;
   1.204 +
   1.205 +	tt_assert(base);
   1.206 +	tt_assert(dns);
   1.207 +	in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */
   1.208 +	dns_ok = 0;
   1.209 +
   1.210 +	req = evdns_base_resolve_reverse(
   1.211 +		dns, &in, 0, dns_gethostbyname_cb, base);
   1.212 +	tt_assert(req);
   1.213 +
   1.214 +	event_base_dispatch(base);
   1.215 +
   1.216 +	tt_int_op(dns_ok, ==, DNS_PTR);
   1.217 +
   1.218 +end:
   1.219 +	if (dns)
   1.220 +		evdns_base_free(dns, 0);
   1.221 +	if (base)
   1.222 +		event_base_free(base);
   1.223 +}
   1.224 +
   1.225 +static int n_server_responses = 0;
   1.226 +
   1.227 +static void
   1.228 +dns_server_request_cb(struct evdns_server_request *req, void *data)
   1.229 +{
   1.230 +	int i, r;
   1.231 +	const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa";
   1.232 +	const char TEST_IN6[] =
   1.233 +	    "f.e.f.e." "0.0.0.0." "0.0.0.0." "1.1.1.1."
   1.234 +	    "a.a.a.a." "0.0.0.0." "0.0.0.0." "0.f.f.f.ip6.arpa";
   1.235 +
   1.236 +	for (i = 0; i < req->nquestions; ++i) {
   1.237 +		const int qtype = req->questions[i]->type;
   1.238 +		const int qclass = req->questions[i]->dns_question_class;
   1.239 +		const char *qname = req->questions[i]->name;
   1.240 +
   1.241 +		struct in_addr ans;
   1.242 +		ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
   1.243 +		if (qtype == EVDNS_TYPE_A &&
   1.244 +		    qclass == EVDNS_CLASS_INET &&
   1.245 +		    !evutil_ascii_strcasecmp(qname, "zz.example.com")) {
   1.246 +			r = evdns_server_request_add_a_reply(req, qname,
   1.247 +			    1, &ans.s_addr, 12345);
   1.248 +			if (r<0)
   1.249 +				dns_ok = 0;
   1.250 +		} else if (qtype == EVDNS_TYPE_AAAA &&
   1.251 +		    qclass == EVDNS_CLASS_INET &&
   1.252 +		    !evutil_ascii_strcasecmp(qname, "zz.example.com")) {
   1.253 +			char addr6[17] = "abcdefghijklmnop";
   1.254 +			r = evdns_server_request_add_aaaa_reply(req,
   1.255 +			    qname, 1, addr6, 123);
   1.256 +			if (r<0)
   1.257 +				dns_ok = 0;
   1.258 +		} else if (qtype == EVDNS_TYPE_PTR &&
   1.259 +		    qclass == EVDNS_CLASS_INET &&
   1.260 +		    !evutil_ascii_strcasecmp(qname, TEST_ARPA)) {
   1.261 +			r = evdns_server_request_add_ptr_reply(req, NULL,
   1.262 +			    qname, "ZZ.EXAMPLE.COM", 54321);
   1.263 +			if (r<0)
   1.264 +				dns_ok = 0;
   1.265 +		} else if (qtype == EVDNS_TYPE_PTR &&
   1.266 +		    qclass == EVDNS_CLASS_INET &&
   1.267 +		    !evutil_ascii_strcasecmp(qname, TEST_IN6)){
   1.268 +			r = evdns_server_request_add_ptr_reply(req, NULL,
   1.269 +			    qname,
   1.270 +			    "ZZ-INET6.EXAMPLE.COM", 54322);
   1.271 +			if (r<0)
   1.272 +				dns_ok = 0;
   1.273 +		} else if (qtype == EVDNS_TYPE_A &&
   1.274 +		    qclass == EVDNS_CLASS_INET &&
   1.275 +		    !evutil_ascii_strcasecmp(qname, "drop.example.com")) {
   1.276 +			if (evdns_server_request_drop(req)<0)
   1.277 +				dns_ok = 0;
   1.278 +			return;
   1.279 +		} else {
   1.280 +			printf("Unexpected question %d %d \"%s\" ",
   1.281 +			    qtype, qclass, qname);
   1.282 +			dns_ok = 0;
   1.283 +		}
   1.284 +	}
   1.285 +	r = evdns_server_request_respond(req, 0);
   1.286 +	if (r<0) {
   1.287 +		printf("Couldn't send reply. ");
   1.288 +		dns_ok = 0;
   1.289 +	}
   1.290 +}
   1.291 +
   1.292 +static void
   1.293 +dns_server_gethostbyname_cb(int result, char type, int count, int ttl,
   1.294 +    void *addresses, void *arg)
   1.295 +{
   1.296 +	if (result == DNS_ERR_CANCEL) {
   1.297 +		if (arg != (void*)(char*)90909) {
   1.298 +			printf("Unexpected cancelation");
   1.299 +			dns_ok = 0;
   1.300 +		}
   1.301 +		dns_got_cancel = 1;
   1.302 +		goto out;
   1.303 +	}
   1.304 +	if (result != DNS_ERR_NONE) {
   1.305 +		printf("Unexpected result %d. ", result);
   1.306 +		dns_ok = 0;
   1.307 +		goto out;
   1.308 +	}
   1.309 +	if (count != 1) {
   1.310 +		printf("Unexpected answer count %d. ", count);
   1.311 +		dns_ok = 0;
   1.312 +		goto out;
   1.313 +	}
   1.314 +	switch (type) {
   1.315 +	case DNS_IPv4_A: {
   1.316 +		struct in_addr *in_addrs = addresses;
   1.317 +		if (in_addrs[0].s_addr != htonl(0xc0a80b0bUL) || ttl != 12345) {
   1.318 +			printf("Bad IPv4 response \"%s\" %d. ",
   1.319 +					inet_ntoa(in_addrs[0]), ttl);
   1.320 +			dns_ok = 0;
   1.321 +			goto out;
   1.322 +		}
   1.323 +		break;
   1.324 +	}
   1.325 +	case DNS_IPv6_AAAA: {
   1.326 +#if defined (_EVENT_HAVE_STRUCT_IN6_ADDR) && defined(_EVENT_HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
   1.327 +		struct in6_addr *in6_addrs = addresses;
   1.328 +		char buf[INET6_ADDRSTRLEN+1];
   1.329 +		if (memcmp(&in6_addrs[0].s6_addr, "abcdefghijklmnop", 16)
   1.330 +		    || ttl != 123) {
   1.331 +			const char *b = evutil_inet_ntop(AF_INET6, &in6_addrs[0],buf,sizeof(buf));
   1.332 +			printf("Bad IPv6 response \"%s\" %d. ", b, ttl);
   1.333 +			dns_ok = 0;
   1.334 +			goto out;
   1.335 +		}
   1.336 +#endif
   1.337 +		break;
   1.338 +	}
   1.339 +	case DNS_PTR: {
   1.340 +		char **addrs = addresses;
   1.341 +		if (arg != (void*)6) {
   1.342 +			if (strcmp(addrs[0], "ZZ.EXAMPLE.COM") ||
   1.343 +			    ttl != 54321) {
   1.344 +				printf("Bad PTR response \"%s\" %d. ",
   1.345 +				    addrs[0], ttl);
   1.346 +				dns_ok = 0;
   1.347 +				goto out;
   1.348 +			}
   1.349 +		} else {
   1.350 +			if (strcmp(addrs[0], "ZZ-INET6.EXAMPLE.COM") ||
   1.351 +			    ttl != 54322) {
   1.352 +				printf("Bad ipv6 PTR response \"%s\" %d. ",
   1.353 +				    addrs[0], ttl);
   1.354 +				dns_ok = 0;
   1.355 +				goto out;
   1.356 +			}
   1.357 +		}
   1.358 +		break;
   1.359 +	}
   1.360 +	default:
   1.361 +		printf("Bad response type %d. ", type);
   1.362 +		dns_ok = 0;
   1.363 +	}
   1.364 + out:
   1.365 +	if (++n_server_responses == 3) {
   1.366 +		event_loopexit(NULL);
   1.367 +	}
   1.368 +}
   1.369 +
   1.370 +static void
   1.371 +dns_server(void)
   1.372 +{
   1.373 +	evutil_socket_t sock=-1;
   1.374 +	struct sockaddr_in my_addr;
   1.375 +	struct sockaddr_storage ss;
   1.376 +	ev_socklen_t slen;
   1.377 +	struct evdns_server_port *port=NULL;
   1.378 +	struct in_addr resolve_addr;
   1.379 +	struct in6_addr resolve_addr6;
   1.380 +	struct evdns_base *base=NULL;
   1.381 +	struct evdns_request *req=NULL;
   1.382 +
   1.383 +	dns_ok = 1;
   1.384 +
   1.385 +	base = evdns_base_new(NULL, 0);
   1.386 +
   1.387 +	/* Now configure a nameserver port. */
   1.388 +	sock = socket(AF_INET, SOCK_DGRAM, 0);
   1.389 +	if (sock<0) {
   1.390 +		tt_abort_perror("socket");
   1.391 +	}
   1.392 +
   1.393 +	evutil_make_socket_nonblocking(sock);
   1.394 +
   1.395 +	memset(&my_addr, 0, sizeof(my_addr));
   1.396 +	my_addr.sin_family = AF_INET;
   1.397 +	my_addr.sin_port = 0; /* kernel picks */
   1.398 +	my_addr.sin_addr.s_addr = htonl(0x7f000001UL);
   1.399 +	if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) {
   1.400 +		tt_abort_perror("bind");
   1.401 +	}
   1.402 +	slen = sizeof(ss);
   1.403 +	if (getsockname(sock, (struct sockaddr*)&ss, &slen) < 0) {
   1.404 +		tt_abort_perror("getsockname");
   1.405 +	}
   1.406 +
   1.407 +	port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL);
   1.408 +
   1.409 +	/* Add ourself as the only nameserver, and make sure we really are
   1.410 +	 * the only nameserver. */
   1.411 +	evdns_base_nameserver_sockaddr_add(base, (struct sockaddr*)&ss, slen, 0);
   1.412 +	tt_int_op(evdns_base_count_nameservers(base), ==, 1);
   1.413 +
   1.414 +	/* Send some queries. */
   1.415 +	evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
   1.416 +					   dns_server_gethostbyname_cb, NULL);
   1.417 +	evdns_base_resolve_ipv6(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
   1.418 +					   dns_server_gethostbyname_cb, NULL);
   1.419 +	resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
   1.420 +	evdns_base_resolve_reverse(base, &resolve_addr, 0,
   1.421 +	    dns_server_gethostbyname_cb, NULL);
   1.422 +	memcpy(resolve_addr6.s6_addr,
   1.423 +	    "\xff\xf0\x00\x00\x00\x00\xaa\xaa"
   1.424 +	    "\x11\x11\x00\x00\x00\x00\xef\xef", 16);
   1.425 +	evdns_base_resolve_reverse_ipv6(base, &resolve_addr6, 0,
   1.426 +	    dns_server_gethostbyname_cb, (void*)6);
   1.427 +
   1.428 +	req = evdns_base_resolve_ipv4(base,
   1.429 +	    "drop.example.com", DNS_QUERY_NO_SEARCH,
   1.430 +	    dns_server_gethostbyname_cb, (void*)(char*)90909);
   1.431 +
   1.432 +	evdns_cancel_request(base, req);
   1.433 +
   1.434 +	event_dispatch();
   1.435 +
   1.436 +	tt_assert(dns_got_cancel);
   1.437 +	test_ok = dns_ok;
   1.438 +
   1.439 +end:
   1.440 +	if (port)
   1.441 +		evdns_close_server_port(port);
   1.442 +	if (sock >= 0)
   1.443 +		evutil_closesocket(sock);
   1.444 +	if (base)
   1.445 +		evdns_base_free(base, 0);
   1.446 +}
   1.447 +
   1.448 +static int n_replies_left;
   1.449 +static struct event_base *exit_base;
   1.450 +
   1.451 +struct generic_dns_callback_result {
   1.452 +	int result;
   1.453 +	char type;
   1.454 +	int count;
   1.455 +	int ttl;
   1.456 +	size_t addrs_len;
   1.457 +	void *addrs;
   1.458 +	char addrs_buf[256];
   1.459 +};
   1.460 +
   1.461 +static void
   1.462 +generic_dns_callback(int result, char type, int count, int ttl, void *addresses,
   1.463 +    void *arg)
   1.464 +{
   1.465 +	size_t len;
   1.466 +	struct generic_dns_callback_result *res = arg;
   1.467 +	res->result = result;
   1.468 +	res->type = type;
   1.469 +	res->count = count;
   1.470 +	res->ttl = ttl;
   1.471 +
   1.472 +	if (type == DNS_IPv4_A)
   1.473 +		len = count * 4;
   1.474 +	else if (type == DNS_IPv6_AAAA)
   1.475 +		len = count * 16;
   1.476 +	else if (type == DNS_PTR)
   1.477 +		len = strlen(addresses)+1;
   1.478 +	else {
   1.479 +		res->addrs_len = len = 0;
   1.480 +		res->addrs = NULL;
   1.481 +	}
   1.482 +	if (len) {
   1.483 +		res->addrs_len = len;
   1.484 +		if (len > 256)
   1.485 +			len = 256;
   1.486 +		memcpy(res->addrs_buf, addresses, len);
   1.487 +		res->addrs = res->addrs_buf;
   1.488 +	}
   1.489 +
   1.490 +	if (--n_replies_left == 0)
   1.491 +		event_base_loopexit(exit_base, NULL);
   1.492 +}
   1.493 +
   1.494 +static struct regress_dns_server_table search_table[] = {
   1.495 +	{ "host.a.example.com", "err", "3", 0 },
   1.496 +	{ "host.b.example.com", "err", "3", 0 },
   1.497 +	{ "host.c.example.com", "A", "11.22.33.44", 0 },
   1.498 +	{ "host2.a.example.com", "err", "3", 0 },
   1.499 +	{ "host2.b.example.com", "A", "200.100.0.100", 0 },
   1.500 +	{ "host2.c.example.com", "err", "3", 0 },
   1.501 +	{ "hostn.a.example.com", "errsoa", "0", 0 },
   1.502 +	{ "hostn.b.example.com", "errsoa", "3", 0 },
   1.503 +	{ "hostn.c.example.com", "err", "0", 0 },
   1.504 +
   1.505 +	{ "host", "err", "3", 0 },
   1.506 +	{ "host2", "err", "3", 0 },
   1.507 +	{ "*", "err", "3", 0 },
   1.508 +	{ NULL, NULL, NULL, 0 }
   1.509 +};
   1.510 +
   1.511 +static void
   1.512 +dns_search_test(void *arg)
   1.513 +{
   1.514 +	struct basic_test_data *data = arg;
   1.515 +	struct event_base *base = data->base;
   1.516 +	struct evdns_base *dns = NULL;
   1.517 +	ev_uint16_t portnum = 0;
   1.518 +	char buf[64];
   1.519 +
   1.520 +	struct generic_dns_callback_result r[8];
   1.521 +
   1.522 +	tt_assert(regress_dnsserver(base, &portnum, search_table));
   1.523 +	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
   1.524 +
   1.525 +	dns = evdns_base_new(base, 0);
   1.526 +	tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
   1.527 +
   1.528 +	evdns_base_search_add(dns, "a.example.com");
   1.529 +	evdns_base_search_add(dns, "b.example.com");
   1.530 +	evdns_base_search_add(dns, "c.example.com");
   1.531 +
   1.532 +	n_replies_left = sizeof(r)/sizeof(r[0]);
   1.533 +	exit_base = base;
   1.534 +
   1.535 +	evdns_base_resolve_ipv4(dns, "host", 0, generic_dns_callback, &r[0]);
   1.536 +	evdns_base_resolve_ipv4(dns, "host2", 0, generic_dns_callback, &r[1]);
   1.537 +	evdns_base_resolve_ipv4(dns, "host", DNS_NO_SEARCH, generic_dns_callback, &r[2]);
   1.538 +	evdns_base_resolve_ipv4(dns, "host2", DNS_NO_SEARCH, generic_dns_callback, &r[3]);
   1.539 +	evdns_base_resolve_ipv4(dns, "host3", 0, generic_dns_callback, &r[4]);
   1.540 +	evdns_base_resolve_ipv4(dns, "hostn.a.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[5]);
   1.541 +	evdns_base_resolve_ipv4(dns, "hostn.b.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[6]);
   1.542 +	evdns_base_resolve_ipv4(dns, "hostn.c.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[7]);
   1.543 +
   1.544 +	event_base_dispatch(base);
   1.545 +
   1.546 +	tt_int_op(r[0].type, ==, DNS_IPv4_A);
   1.547 +	tt_int_op(r[0].count, ==, 1);
   1.548 +	tt_int_op(((ev_uint32_t*)r[0].addrs)[0], ==, htonl(0x0b16212c));
   1.549 +	tt_int_op(r[1].type, ==, DNS_IPv4_A);
   1.550 +	tt_int_op(r[1].count, ==, 1);
   1.551 +	tt_int_op(((ev_uint32_t*)r[1].addrs)[0], ==, htonl(0xc8640064));
   1.552 +	tt_int_op(r[2].result, ==, DNS_ERR_NOTEXIST);
   1.553 +	tt_int_op(r[3].result, ==, DNS_ERR_NOTEXIST);
   1.554 +	tt_int_op(r[4].result, ==, DNS_ERR_NOTEXIST);
   1.555 +	tt_int_op(r[5].result, ==, DNS_ERR_NODATA);
   1.556 +	tt_int_op(r[5].ttl, ==, 42);
   1.557 +	tt_int_op(r[6].result, ==, DNS_ERR_NOTEXIST);
   1.558 +	tt_int_op(r[6].ttl, ==, 42);
   1.559 +	tt_int_op(r[7].result, ==, DNS_ERR_NODATA);
   1.560 +	tt_int_op(r[7].ttl, ==, 0);
   1.561 +
   1.562 +end:
   1.563 +	if (dns)
   1.564 +		evdns_base_free(dns, 0);
   1.565 +
   1.566 +	regress_clean_dnsserver();
   1.567 +}
   1.568 +
   1.569 +static int request_count = 0;
   1.570 +static struct evdns_request *current_req = NULL;
   1.571 +
   1.572 +static void
   1.573 +search_cancel_server_cb(struct evdns_server_request *req, void *data)
   1.574 +{
   1.575 +	const char *question;
   1.576 +
   1.577 +	if (req->nquestions != 1)
   1.578 +		TT_DIE(("Only handling one question at a time; got %d",
   1.579 +			req->nquestions));
   1.580 +
   1.581 +	question = req->questions[0]->name;
   1.582 +
   1.583 +	TT_BLATHER(("got question, %s", question));
   1.584 +
   1.585 +	tt_assert(request_count > 0);
   1.586 +	tt_assert(!evdns_server_request_respond(req, 3));
   1.587 +
   1.588 +	if (!--request_count)
   1.589 +		evdns_cancel_request(NULL, current_req);
   1.590 +
   1.591 +end:
   1.592 +	;
   1.593 +}
   1.594 +
   1.595 +static void
   1.596 +dns_search_cancel_test(void *arg)
   1.597 +{
   1.598 +	struct basic_test_data *data = arg;
   1.599 +	struct event_base *base = data->base;
   1.600 +	struct evdns_base *dns = NULL;
   1.601 +	struct evdns_server_port *port = NULL;
   1.602 +	ev_uint16_t portnum = 0;
   1.603 +	struct generic_dns_callback_result r1;
   1.604 +	char buf[64];
   1.605 +
   1.606 +	port = regress_get_dnsserver(base, &portnum, NULL,
   1.607 +	    search_cancel_server_cb, NULL);
   1.608 +	tt_assert(port);
   1.609 +	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
   1.610 +
   1.611 +	dns = evdns_base_new(base, 0);
   1.612 +	tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
   1.613 +
   1.614 +	evdns_base_search_add(dns, "a.example.com");
   1.615 +	evdns_base_search_add(dns, "b.example.com");
   1.616 +	evdns_base_search_add(dns, "c.example.com");
   1.617 +	evdns_base_search_add(dns, "d.example.com");
   1.618 +
   1.619 +	exit_base = base;
   1.620 +	request_count = 3;
   1.621 +	n_replies_left = 1;
   1.622 +
   1.623 +	current_req = evdns_base_resolve_ipv4(dns, "host", 0,
   1.624 +					generic_dns_callback, &r1);
   1.625 +	event_base_dispatch(base);
   1.626 +
   1.627 +	tt_int_op(r1.result, ==, DNS_ERR_CANCEL);
   1.628 +
   1.629 +end:
   1.630 +	if (port)
   1.631 +		evdns_close_server_port(port);
   1.632 +	if (dns)
   1.633 +		evdns_base_free(dns, 0);
   1.634 +}
   1.635 +
   1.636 +static void
   1.637 +fail_server_cb(struct evdns_server_request *req, void *data)
   1.638 +{
   1.639 +	const char *question;
   1.640 +	int *count = data;
   1.641 +	struct in_addr in;
   1.642 +
   1.643 +	/* Drop the first N requests that we get. */
   1.644 +	if (*count > 0) {
   1.645 +		--*count;
   1.646 +		tt_want(! evdns_server_request_drop(req));
   1.647 +		return;
   1.648 +	}
   1.649 +
   1.650 +	if (req->nquestions != 1)
   1.651 +		TT_DIE(("Only handling one question at a time; got %d",
   1.652 +			req->nquestions));
   1.653 +
   1.654 +	question = req->questions[0]->name;
   1.655 +
   1.656 +	if (!evutil_ascii_strcasecmp(question, "google.com")) {
   1.657 +		/* Detect a probe, and get out of the loop. */
   1.658 +		event_base_loopexit(exit_base, NULL);
   1.659 +	}
   1.660 +
   1.661 +	evutil_inet_pton(AF_INET, "16.32.64.128", &in);
   1.662 +	evdns_server_request_add_a_reply(req, question, 1, &in.s_addr,
   1.663 +	    100);
   1.664 +	tt_assert(! evdns_server_request_respond(req, 0))
   1.665 +	return;
   1.666 +end:
   1.667 +	tt_want(! evdns_server_request_drop(req));
   1.668 +}
   1.669 +
   1.670 +static void
   1.671 +dns_retry_test(void *arg)
   1.672 +{
   1.673 +	struct basic_test_data *data = arg;
   1.674 +	struct event_base *base = data->base;
   1.675 +	struct evdns_server_port *port = NULL;
   1.676 +	struct evdns_base *dns = NULL;
   1.677 +	int drop_count = 2;
   1.678 +	ev_uint16_t portnum = 0;
   1.679 +	char buf[64];
   1.680 +
   1.681 +	struct generic_dns_callback_result r1;
   1.682 +
   1.683 +	port = regress_get_dnsserver(base, &portnum, NULL,
   1.684 +	    fail_server_cb, &drop_count);
   1.685 +	tt_assert(port);
   1.686 +	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
   1.687 +
   1.688 +	dns = evdns_base_new(base, 0);
   1.689 +	tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
   1.690 +	tt_assert(! evdns_base_set_option(dns, "timeout", "0.3"));
   1.691 +	tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "10"));
   1.692 +	tt_assert(! evdns_base_set_option(dns, "initial-probe-timeout", "0.5"));
   1.693 +
   1.694 +	evdns_base_resolve_ipv4(dns, "host.example.com", 0,
   1.695 +	    generic_dns_callback, &r1);
   1.696 +
   1.697 +	n_replies_left = 1;
   1.698 +	exit_base = base;
   1.699 +
   1.700 +	event_base_dispatch(base);
   1.701 +
   1.702 +	tt_int_op(drop_count, ==, 0);
   1.703 +
   1.704 +	tt_int_op(r1.type, ==, DNS_IPv4_A);
   1.705 +	tt_int_op(r1.count, ==, 1);
   1.706 +	tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x10204080));
   1.707 +
   1.708 +	/* Now try again, but this time have the server get treated as
   1.709 +	 * failed, so we can send it a test probe. */
   1.710 +	drop_count = 4;
   1.711 +	tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "3"));
   1.712 +	tt_assert(! evdns_base_set_option(dns, "attempts:", "4"));
   1.713 +	memset(&r1, 0, sizeof(r1));
   1.714 +
   1.715 +	evdns_base_resolve_ipv4(dns, "host.example.com", 0,
   1.716 +	    generic_dns_callback, &r1);
   1.717 +
   1.718 +	n_replies_left = 2;
   1.719 +
   1.720 +	/* This will run until it answers the "google.com" probe request. */
   1.721 +	event_base_dispatch(base);
   1.722 +
   1.723 +	/* We'll treat the server as failed here. */
   1.724 +	tt_int_op(r1.result, ==, DNS_ERR_TIMEOUT);
   1.725 +
   1.726 +	/* It should work this time. */
   1.727 +	tt_int_op(drop_count, ==, 0);
   1.728 +	evdns_base_resolve_ipv4(dns, "host.example.com", 0,
   1.729 +	    generic_dns_callback, &r1);
   1.730 +
   1.731 +	event_base_dispatch(base);
   1.732 +	tt_int_op(r1.result, ==, DNS_ERR_NONE);
   1.733 +	tt_int_op(r1.type, ==, DNS_IPv4_A);
   1.734 +	tt_int_op(r1.count, ==, 1);
   1.735 +	tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x10204080));
   1.736 +
   1.737 +end:
   1.738 +	if (dns)
   1.739 +		evdns_base_free(dns, 0);
   1.740 +	if (port)
   1.741 +		evdns_close_server_port(port);
   1.742 +}
   1.743 +
   1.744 +static struct regress_dns_server_table internal_error_table[] = {
   1.745 +	/* Error 4 (NOTIMPL) makes us reissue the request to another server
   1.746 +	   if we can.
   1.747 +
   1.748 +	   XXXX we should reissue under a much wider set of circumstances!
   1.749 +	 */
   1.750 +	{ "foof.example.com", "err", "4", 0 },
   1.751 +	{ NULL, NULL, NULL, 0 }
   1.752 +};
   1.753 +
   1.754 +static struct regress_dns_server_table reissue_table[] = {
   1.755 +	{ "foof.example.com", "A", "240.15.240.15", 0 },
   1.756 +	{ NULL, NULL, NULL, 0 }
   1.757 +};
   1.758 +
   1.759 +static void
   1.760 +dns_reissue_test(void *arg)
   1.761 +{
   1.762 +	struct basic_test_data *data = arg;
   1.763 +	struct event_base *base = data->base;
   1.764 +	struct evdns_server_port *port1 = NULL, *port2 = NULL;
   1.765 +	struct evdns_base *dns = NULL;
   1.766 +	struct generic_dns_callback_result r1;
   1.767 +	ev_uint16_t portnum1 = 0, portnum2=0;
   1.768 +	char buf1[64], buf2[64];
   1.769 +
   1.770 +	port1 = regress_get_dnsserver(base, &portnum1, NULL,
   1.771 +	    regress_dns_server_cb, internal_error_table);
   1.772 +	tt_assert(port1);
   1.773 +	port2 = regress_get_dnsserver(base, &portnum2, NULL,
   1.774 +	    regress_dns_server_cb, reissue_table);
   1.775 +	tt_assert(port2);
   1.776 +	evutil_snprintf(buf1, sizeof(buf1), "127.0.0.1:%d", (int)portnum1);
   1.777 +	evutil_snprintf(buf2, sizeof(buf2), "127.0.0.1:%d", (int)portnum2);
   1.778 +
   1.779 +	dns = evdns_base_new(base, 0);
   1.780 +	tt_assert(!evdns_base_nameserver_ip_add(dns, buf1));
   1.781 +	tt_assert(! evdns_base_set_option(dns, "timeout:", "0.3"));
   1.782 +	tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2"));
   1.783 +	tt_assert(! evdns_base_set_option(dns, "attempts:", "5"));
   1.784 +
   1.785 +	memset(&r1, 0, sizeof(r1));
   1.786 +	evdns_base_resolve_ipv4(dns, "foof.example.com", 0,
   1.787 +	    generic_dns_callback, &r1);
   1.788 +
   1.789 +	/* Add this after, so that we are sure to get a reissue. */
   1.790 +	tt_assert(!evdns_base_nameserver_ip_add(dns, buf2));
   1.791 +
   1.792 +	n_replies_left = 1;
   1.793 +	exit_base = base;
   1.794 +
   1.795 +	event_base_dispatch(base);
   1.796 +	tt_int_op(r1.result, ==, DNS_ERR_NONE);
   1.797 +	tt_int_op(r1.type, ==, DNS_IPv4_A);
   1.798 +	tt_int_op(r1.count, ==, 1);
   1.799 +	tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0xf00ff00f));
   1.800 +
   1.801 +	/* Make sure we dropped at least once. */
   1.802 +	tt_int_op(internal_error_table[0].seen, >, 0);
   1.803 +
   1.804 +end:
   1.805 +	if (dns)
   1.806 +		evdns_base_free(dns, 0);
   1.807 +	if (port1)
   1.808 +		evdns_close_server_port(port1);
   1.809 +	if (port2)
   1.810 +		evdns_close_server_port(port2);
   1.811 +}
   1.812 +
   1.813 +#if 0
   1.814 +static void
   1.815 +dumb_bytes_fn(char *p, size_t n)
   1.816 +{
   1.817 +	unsigned i;
   1.818 +	/* This gets us 6 bits of entropy per transaction ID, which means we
   1.819 +	 * will have probably have collisions and need to pick again. */
   1.820 +	for (i=0;i<n;++i)
   1.821 +		p[i] = (char)(rand() & 7);
   1.822 +}
   1.823 +#endif
   1.824 +
   1.825 +static void
   1.826 +dns_inflight_test(void *arg)
   1.827 +{
   1.828 +	struct basic_test_data *data = arg;
   1.829 +	struct event_base *base = data->base;
   1.830 +	struct evdns_base *dns = NULL;
   1.831 +	ev_uint16_t portnum = 0;
   1.832 +	char buf[64];
   1.833 +
   1.834 +	struct generic_dns_callback_result r[20];
   1.835 +	int i;
   1.836 +
   1.837 +	tt_assert(regress_dnsserver(base, &portnum, reissue_table));
   1.838 +	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
   1.839 +
   1.840 +	dns = evdns_base_new(base, 0);
   1.841 +	tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
   1.842 +	tt_assert(! evdns_base_set_option(dns, "max-inflight:", "3"));
   1.843 +	tt_assert(! evdns_base_set_option(dns, "randomize-case:", "0"));
   1.844 +
   1.845 +	for (i=0;i<20;++i)
   1.846 +		evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r[i]);
   1.847 +
   1.848 +	n_replies_left = 20;
   1.849 +	exit_base = base;
   1.850 +
   1.851 +	event_base_dispatch(base);
   1.852 +
   1.853 +	for (i=0;i<20;++i) {
   1.854 +		tt_int_op(r[i].type, ==, DNS_IPv4_A);
   1.855 +		tt_int_op(r[i].count, ==, 1);
   1.856 +		tt_int_op(((ev_uint32_t*)r[i].addrs)[0], ==, htonl(0xf00ff00f));
   1.857 +	}
   1.858 +
   1.859 +end:
   1.860 +	if (dns)
   1.861 +		evdns_base_free(dns, 0);
   1.862 +	regress_clean_dnsserver();
   1.863 +}
   1.864 +
   1.865 +/* === Test for bufferevent_socket_connect_hostname */
   1.866 +
   1.867 +static int total_connected_or_failed = 0;
   1.868 +static int total_n_accepted = 0;
   1.869 +static struct event_base *be_connect_hostname_base = NULL;
   1.870 +
   1.871 +/* Implements a DNS server for the connect_hostname test and the
   1.872 + * getaddrinfo_async test */
   1.873 +static void
   1.874 +be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data)
   1.875 +{
   1.876 +	int i;
   1.877 +	int *n_got_p=data;
   1.878 +	int added_any=0;
   1.879 +	++*n_got_p;
   1.880 +
   1.881 +	for (i=0;i<req->nquestions;++i) {
   1.882 +		const int qtype = req->questions[i]->type;
   1.883 +		const int qclass = req->questions[i]->dns_question_class;
   1.884 +		const char *qname = req->questions[i]->name;
   1.885 +		struct in_addr ans;
   1.886 +		struct in6_addr ans6;
   1.887 +		memset(&ans6, 0, sizeof(ans6));
   1.888 +
   1.889 +		if (qtype == EVDNS_TYPE_A &&
   1.890 +		    qclass == EVDNS_CLASS_INET &&
   1.891 +		    !evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) {
   1.892 +			ans.s_addr = htonl(0x7f000001);
   1.893 +			evdns_server_request_add_a_reply(req, qname,
   1.894 +			    1, &ans.s_addr, 2000);
   1.895 +			added_any = 1;
   1.896 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.897 +			"nosuchplace.example.com")) {
   1.898 +			/* ok, just say notfound. */
   1.899 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.900 +			"both.example.com")) {
   1.901 +			if (qtype == EVDNS_TYPE_A) {
   1.902 +				ans.s_addr = htonl(0x50502020);
   1.903 +				evdns_server_request_add_a_reply(req, qname,
   1.904 +				    1, &ans.s_addr, 2000);
   1.905 +				added_any = 1;
   1.906 +			} else if (qtype == EVDNS_TYPE_AAAA) {
   1.907 +				ans6.s6_addr[0] = 0x80;
   1.908 +				ans6.s6_addr[1] = 0xff;
   1.909 +				ans6.s6_addr[14] = 0xbb;
   1.910 +				ans6.s6_addr[15] = 0xbb;
   1.911 +				evdns_server_request_add_aaaa_reply(req, qname,
   1.912 +				    1, &ans6.s6_addr, 2000);
   1.913 +				added_any = 1;
   1.914 +			}
   1.915 +			evdns_server_request_add_cname_reply(req, qname,
   1.916 +			    "both-canonical.example.com", 1000);
   1.917 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.918 +			"v4only.example.com") ||
   1.919 +		    !evutil_ascii_strcasecmp(qname, "v4assert.example.com")) {
   1.920 +			if (qtype == EVDNS_TYPE_A) {
   1.921 +				ans.s_addr = htonl(0x12345678);
   1.922 +				evdns_server_request_add_a_reply(req, qname,
   1.923 +				    1, &ans.s_addr, 2000);
   1.924 +				added_any = 1;
   1.925 +			} else if (!evutil_ascii_strcasecmp(qname,
   1.926 +				"v4assert.example.com")) {
   1.927 +				TT_FAIL(("Got an AAAA request for v4assert"));
   1.928 +			}
   1.929 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.930 +			"v6only.example.com") ||
   1.931 +		    !evutil_ascii_strcasecmp(qname, "v6assert.example.com")) {
   1.932 +			if (qtype == EVDNS_TYPE_AAAA) {
   1.933 +				ans6.s6_addr[0] = 0x0b;
   1.934 +				ans6.s6_addr[1] = 0x0b;
   1.935 +				ans6.s6_addr[14] = 0xf0;
   1.936 +				ans6.s6_addr[15] = 0x0d;
   1.937 +				evdns_server_request_add_aaaa_reply(req, qname,
   1.938 +				    1, &ans6.s6_addr, 2000);
   1.939 +				added_any = 1;
   1.940 +			}  else if (!evutil_ascii_strcasecmp(qname,
   1.941 +				"v6assert.example.com")) {
   1.942 +				TT_FAIL(("Got a A request for v6assert"));
   1.943 +			}
   1.944 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.945 +			"v6timeout.example.com")) {
   1.946 +			if (qtype == EVDNS_TYPE_A) {
   1.947 +				ans.s_addr = htonl(0xabcdef01);
   1.948 +				evdns_server_request_add_a_reply(req, qname,
   1.949 +				    1, &ans.s_addr, 2000);
   1.950 +				added_any = 1;
   1.951 +			} else if (qtype == EVDNS_TYPE_AAAA) {
   1.952 +				/* Let the v6 request time out.*/
   1.953 +				evdns_server_request_drop(req);
   1.954 +				return;
   1.955 +			}
   1.956 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.957 +			"v4timeout.example.com")) {
   1.958 +			if (qtype == EVDNS_TYPE_AAAA) {
   1.959 +				ans6.s6_addr[0] = 0x0a;
   1.960 +				ans6.s6_addr[1] = 0x0a;
   1.961 +				ans6.s6_addr[14] = 0xff;
   1.962 +				ans6.s6_addr[15] = 0x01;
   1.963 +				evdns_server_request_add_aaaa_reply(req, qname,
   1.964 +				    1, &ans6.s6_addr, 2000);
   1.965 +				added_any = 1;
   1.966 +			} else if (qtype == EVDNS_TYPE_A) {
   1.967 +				/* Let the v4 request time out.*/
   1.968 +				evdns_server_request_drop(req);
   1.969 +				return;
   1.970 +			}
   1.971 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.972 +			"v6timeout-nonexist.example.com")) {
   1.973 +			if (qtype == EVDNS_TYPE_A) {
   1.974 +				/* Fall through, give an nexist. */
   1.975 +			} else if (qtype == EVDNS_TYPE_AAAA) {
   1.976 +				/* Let the v6 request time out.*/
   1.977 +				evdns_server_request_drop(req);
   1.978 +				return;
   1.979 +			}
   1.980 +		} else if (!evutil_ascii_strcasecmp(qname,
   1.981 +			"all-timeout.example.com")) {
   1.982 +			/* drop all requests */
   1.983 +			evdns_server_request_drop(req);
   1.984 +			return;
   1.985 +		} else {
   1.986 +			TT_GRIPE(("Got weird request for %s",qname));
   1.987 +		}
   1.988 +	}
   1.989 +	if (added_any)
   1.990 +		evdns_server_request_respond(req, 0);
   1.991 +	else
   1.992 +		evdns_server_request_respond(req, 3);
   1.993 +}
   1.994 +
   1.995 +/* Implements a listener for connect_hostname test. */
   1.996 +static void
   1.997 +nil_accept_cb(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *s,
   1.998 +    int socklen, void *arg)
   1.999 +{
  1.1000 +	int *p = arg;
  1.1001 +	(*p)++;
  1.1002 +	++total_n_accepted;
  1.1003 +	/* don't do anything with the socket; let it close when we exit() */
  1.1004 +	if (total_n_accepted >= 3 && total_connected_or_failed >= 5)
  1.1005 +		event_base_loopexit(be_connect_hostname_base,
  1.1006 +		    NULL);
  1.1007 +}
  1.1008 +
  1.1009 +struct be_conn_hostname_result {
  1.1010 +	int dnserr;
  1.1011 +	int what;
  1.1012 +};
  1.1013 +
  1.1014 +/* Bufferevent event callback for the connect_hostname test: remembers what
  1.1015 + * event we got. */
  1.1016 +static void
  1.1017 +be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx)
  1.1018 +{
  1.1019 +	struct be_conn_hostname_result *got = ctx;
  1.1020 +	if (!got->what) {
  1.1021 +		TT_BLATHER(("Got a bufferevent event %d", what));
  1.1022 +		got->what = what;
  1.1023 +
  1.1024 +		if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
  1.1025 +			int r;
  1.1026 +			if ((r = bufferevent_socket_get_dns_error(bev))) {
  1.1027 +				got->dnserr = r;
  1.1028 +				TT_BLATHER(("DNS error %d: %s", r,
  1.1029 +					   evutil_gai_strerror(r)));
  1.1030 +			}			++total_connected_or_failed;
  1.1031 +			TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
  1.1032 +
  1.1033 +			if (total_n_accepted >= 3 && total_connected_or_failed >= 5)
  1.1034 +				event_base_loopexit(be_connect_hostname_base,
  1.1035 +				    NULL);
  1.1036 +		}
  1.1037 +	} else {
  1.1038 +		TT_FAIL(("Two events on one bufferevent. %d,%d",
  1.1039 +			got->what, (int)what));
  1.1040 +	}
  1.1041 +}
  1.1042 +
  1.1043 +static void
  1.1044 +test_bufferevent_connect_hostname(void *arg)
  1.1045 +{
  1.1046 +	struct basic_test_data *data = arg;
  1.1047 +	struct evconnlistener *listener = NULL;
  1.1048 +	struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL;
  1.1049 +	struct be_conn_hostname_result be1_outcome={0,0}, be2_outcome={0,0},
  1.1050 +	       be3_outcome={0,0}, be4_outcome={0,0}, be5_outcome={0,0};
  1.1051 +	int expect_err5;
  1.1052 +	struct evdns_base *dns=NULL;
  1.1053 +	struct evdns_server_port *port=NULL;
  1.1054 +	struct sockaddr_in sin;
  1.1055 +	int listener_port=-1;
  1.1056 +	ev_uint16_t dns_port=0;
  1.1057 +	int n_accept=0, n_dns=0;
  1.1058 +	char buf[128];
  1.1059 +
  1.1060 +	be_connect_hostname_base = data->base;
  1.1061 +
  1.1062 +	/* Bind an address and figure out what port it's on. */
  1.1063 +	memset(&sin, 0, sizeof(sin));
  1.1064 +	sin.sin_family = AF_INET;
  1.1065 +	sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
  1.1066 +	sin.sin_port = 0;
  1.1067 +	listener = evconnlistener_new_bind(data->base, nil_accept_cb,
  1.1068 +	    &n_accept,
  1.1069 +	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC,
  1.1070 +	    -1, (struct sockaddr *)&sin, sizeof(sin));
  1.1071 +	tt_assert(listener);
  1.1072 +	listener_port = regress_get_socket_port(
  1.1073 +		evconnlistener_get_fd(listener));
  1.1074 +
  1.1075 +	port = regress_get_dnsserver(data->base, &dns_port, NULL,
  1.1076 +	    be_getaddrinfo_server_cb, &n_dns);
  1.1077 +	tt_assert(port);
  1.1078 +	tt_int_op(dns_port, >=, 0);
  1.1079 +
  1.1080 +	/* Start an evdns_base that uses the server as its resolver. */
  1.1081 +	dns = evdns_base_new(data->base, 0);
  1.1082 +	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)dns_port);
  1.1083 +	evdns_base_nameserver_ip_add(dns, buf);
  1.1084 +
  1.1085 +	/* Now, finally, at long last, launch the bufferevents.	 One should do
  1.1086 +	 * a failing lookup IP, one should do a successful lookup by IP,
  1.1087 +	 * and one should do a successful lookup by hostname. */
  1.1088 +	be1 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
  1.1089 +	be2 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
  1.1090 +	be3 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
  1.1091 +	be4 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
  1.1092 +	be5 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE);
  1.1093 +
  1.1094 +	bufferevent_setcb(be1, NULL, NULL, be_connect_hostname_event_cb,
  1.1095 +	    &be1_outcome);
  1.1096 +	bufferevent_setcb(be2, NULL, NULL, be_connect_hostname_event_cb,
  1.1097 +	    &be2_outcome);
  1.1098 +	bufferevent_setcb(be3, NULL, NULL, be_connect_hostname_event_cb,
  1.1099 +	    &be3_outcome);
  1.1100 +	bufferevent_setcb(be4, NULL, NULL, be_connect_hostname_event_cb,
  1.1101 +	    &be4_outcome);
  1.1102 +	bufferevent_setcb(be5, NULL, NULL, be_connect_hostname_event_cb,
  1.1103 +	    &be5_outcome);
  1.1104 +
  1.1105 +	/* Launch an async resolve that will fail. */
  1.1106 +	tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET,
  1.1107 +		"nosuchplace.example.com", listener_port));
  1.1108 +	/* Connect to the IP without resolving. */
  1.1109 +	tt_assert(!bufferevent_socket_connect_hostname(be2, dns, AF_INET,
  1.1110 +		"127.0.0.1", listener_port));
  1.1111 +	/* Launch an async resolve that will succeed. */
  1.1112 +	tt_assert(!bufferevent_socket_connect_hostname(be3, dns, AF_INET,
  1.1113 +		"nobodaddy.example.com", listener_port));
  1.1114 +	/* Use the blocking resolver.  This one will fail if your resolver
  1.1115 +	 * can't resolve localhost to 127.0.0.1 */
  1.1116 +	tt_assert(!bufferevent_socket_connect_hostname(be4, NULL, AF_INET,
  1.1117 +		"localhost", listener_port));
  1.1118 +	/* Use the blocking resolver with a nonexistent hostname. */
  1.1119 +	tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET,
  1.1120 +		"nonesuch.nowhere.example.com", 80));
  1.1121 +	{
  1.1122 +		/* The blocking resolver will use the system nameserver, which
  1.1123 +		 * might tell us anything.  (Yes, some twits even pretend that
  1.1124 +		 * example.com is real.) Let's see what answer to expect. */
  1.1125 +		struct evutil_addrinfo hints, *ai = NULL;
  1.1126 +		memset(&hints, 0, sizeof(hints));
  1.1127 +		hints.ai_family = AF_INET;
  1.1128 +		hints.ai_socktype = SOCK_STREAM;
  1.1129 +		hints.ai_protocol = IPPROTO_TCP;
  1.1130 +		expect_err5 = evutil_getaddrinfo(
  1.1131 +			"nonesuch.nowhere.example.com", "80", &hints, &ai);
  1.1132 +	}
  1.1133 +
  1.1134 +	event_base_dispatch(data->base);
  1.1135 +
  1.1136 +	tt_int_op(be1_outcome.what, ==, BEV_EVENT_ERROR);
  1.1137 +	tt_int_op(be1_outcome.dnserr, ==, EVUTIL_EAI_NONAME);
  1.1138 +	tt_int_op(be2_outcome.what, ==, BEV_EVENT_CONNECTED);
  1.1139 +	tt_int_op(be2_outcome.dnserr, ==, 0);
  1.1140 +	tt_int_op(be3_outcome.what, ==, BEV_EVENT_CONNECTED);
  1.1141 +	tt_int_op(be3_outcome.dnserr, ==, 0);
  1.1142 +	tt_int_op(be4_outcome.what, ==, BEV_EVENT_CONNECTED);
  1.1143 +	tt_int_op(be4_outcome.dnserr, ==, 0);
  1.1144 +	if (expect_err5) {
  1.1145 +		tt_int_op(be5_outcome.what, ==, BEV_EVENT_ERROR);
  1.1146 +		tt_int_op(be5_outcome.dnserr, ==, expect_err5);
  1.1147 +	}
  1.1148 +
  1.1149 +	tt_int_op(n_accept, ==, 3);
  1.1150 +	tt_int_op(n_dns, ==, 2);
  1.1151 +
  1.1152 +end:
  1.1153 +	if (listener)
  1.1154 +		evconnlistener_free(listener);
  1.1155 +	if (port)
  1.1156 +		evdns_close_server_port(port);
  1.1157 +	if (dns)
  1.1158 +		evdns_base_free(dns, 0);
  1.1159 +	if (be1)
  1.1160 +		bufferevent_free(be1);
  1.1161 +	if (be2)
  1.1162 +		bufferevent_free(be2);
  1.1163 +	if (be3)
  1.1164 +		bufferevent_free(be3);
  1.1165 +	if (be4)
  1.1166 +		bufferevent_free(be4);
  1.1167 +	if (be5)
  1.1168 +		bufferevent_free(be5);
  1.1169 +}
  1.1170 +
  1.1171 +
  1.1172 +struct gai_outcome {
  1.1173 +	int err;
  1.1174 +	struct evutil_addrinfo *ai;
  1.1175 +};
  1.1176 +
  1.1177 +static int n_gai_results_pending = 0;
  1.1178 +static struct event_base *exit_base_on_no_pending_results = NULL;
  1.1179 +
  1.1180 +static void
  1.1181 +gai_cb(int err, struct evutil_addrinfo *res, void *ptr)
  1.1182 +{
  1.1183 +	struct gai_outcome *go = ptr;
  1.1184 +	go->err = err;
  1.1185 +	go->ai = res;
  1.1186 +	if (--n_gai_results_pending <= 0 && exit_base_on_no_pending_results)
  1.1187 +		event_base_loopexit(exit_base_on_no_pending_results, NULL);
  1.1188 +	if (n_gai_results_pending < 900)
  1.1189 +		TT_BLATHER(("Got an answer; expecting %d more.",
  1.1190 +			n_gai_results_pending));
  1.1191 +}
  1.1192 +
  1.1193 +static void
  1.1194 +cancel_gai_cb(evutil_socket_t fd, short what, void *ptr)
  1.1195 +{
  1.1196 +	struct evdns_getaddrinfo_request *r = ptr;
  1.1197 +	evdns_getaddrinfo_cancel(r);
  1.1198 +}
  1.1199 +
  1.1200 +static void
  1.1201 +test_getaddrinfo_async(void *arg)
  1.1202 +{
  1.1203 +	struct basic_test_data *data = arg;
  1.1204 +	struct evutil_addrinfo hints, *a;
  1.1205 +	struct gai_outcome local_outcome;
  1.1206 +	struct gai_outcome a_out[12];
  1.1207 +	int i;
  1.1208 +	struct evdns_getaddrinfo_request *r;
  1.1209 +	char buf[128];
  1.1210 +	struct evdns_server_port *port = NULL;
  1.1211 +	ev_uint16_t dns_port = 0;
  1.1212 +	int n_dns_questions = 0;
  1.1213 +
  1.1214 +	struct evdns_base *dns_base = evdns_base_new(data->base, 0);
  1.1215 +	tt_assert(dns_base);
  1.1216 +
  1.1217 +	/* for localhost */
  1.1218 +	evdns_base_load_hosts(dns_base, NULL);
  1.1219 +
  1.1220 +	memset(a_out, 0, sizeof(a_out));
  1.1221 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1222 +
  1.1223 +	n_gai_results_pending = 10000; /* don't think about exiting yet. */
  1.1224 +
  1.1225 +	/* 1. Try some cases that will never hit the asynchronous resolver. */
  1.1226 +	/* 1a. Simple case with a symbolic service name */
  1.1227 +	memset(&hints, 0, sizeof(hints));
  1.1228 +	hints.ai_family = PF_UNSPEC;
  1.1229 +	hints.ai_socktype = SOCK_STREAM;
  1.1230 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1231 +	r = evdns_getaddrinfo(dns_base, "1.2.3.4", "http",
  1.1232 +	    &hints, gai_cb, &local_outcome);
  1.1233 +	tt_assert(! r);
  1.1234 +	if (!local_outcome.err) {
  1.1235 +		tt_ptr_op(local_outcome.ai,!=,NULL);
  1.1236 +		test_ai_eq(local_outcome.ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP);
  1.1237 +		evutil_freeaddrinfo(local_outcome.ai);
  1.1238 +		local_outcome.ai = NULL;
  1.1239 +	} else {
  1.1240 +		TT_BLATHER(("Apparently we have no getservbyname."));
  1.1241 +	}
  1.1242 +
  1.1243 +	/* 1b. EVUTIL_AI_NUMERICHOST is set */
  1.1244 +	memset(&hints, 0, sizeof(hints));
  1.1245 +	hints.ai_family = PF_UNSPEC;
  1.1246 +	hints.ai_flags = EVUTIL_AI_NUMERICHOST;
  1.1247 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1248 +	r = evdns_getaddrinfo(dns_base, "www.google.com", "80",
  1.1249 +	    &hints, gai_cb, &local_outcome);
  1.1250 +	tt_ptr_op(r,==,NULL);
  1.1251 +	tt_int_op(local_outcome.err,==,EVUTIL_EAI_NONAME);
  1.1252 +	tt_ptr_op(local_outcome.ai,==,NULL);
  1.1253 +
  1.1254 +	/* 1c. We give a numeric address (ipv6) */
  1.1255 +	memset(&hints, 0, sizeof(hints));
  1.1256 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1257 +	hints.ai_family = PF_UNSPEC;
  1.1258 +	hints.ai_protocol = IPPROTO_TCP;
  1.1259 +	r = evdns_getaddrinfo(dns_base, "f::f", "8008",
  1.1260 +	    &hints, gai_cb, &local_outcome);
  1.1261 +	tt_assert(!r);
  1.1262 +	tt_int_op(local_outcome.err,==,0);
  1.1263 +	tt_assert(local_outcome.ai);
  1.1264 +	tt_ptr_op(local_outcome.ai->ai_next,==,NULL);
  1.1265 +	test_ai_eq(local_outcome.ai, "[f::f]:8008", SOCK_STREAM, IPPROTO_TCP);
  1.1266 +	evutil_freeaddrinfo(local_outcome.ai);
  1.1267 +	local_outcome.ai = NULL;
  1.1268 +
  1.1269 +	/* 1d. We give a numeric address (ipv4) */
  1.1270 +	memset(&hints, 0, sizeof(hints));
  1.1271 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1272 +	hints.ai_family = PF_UNSPEC;
  1.1273 +	r = evdns_getaddrinfo(dns_base, "5.6.7.8", NULL,
  1.1274 +	    &hints, gai_cb, &local_outcome);
  1.1275 +	tt_assert(!r);
  1.1276 +	tt_int_op(local_outcome.err,==,0);
  1.1277 +	tt_assert(local_outcome.ai);
  1.1278 +	a = ai_find_by_protocol(local_outcome.ai, IPPROTO_TCP);
  1.1279 +	tt_assert(a);
  1.1280 +	test_ai_eq(a, "5.6.7.8", SOCK_STREAM, IPPROTO_TCP);
  1.1281 +	a = ai_find_by_protocol(local_outcome.ai, IPPROTO_UDP);
  1.1282 +	tt_assert(a);
  1.1283 +	test_ai_eq(a, "5.6.7.8", SOCK_DGRAM, IPPROTO_UDP);
  1.1284 +	evutil_freeaddrinfo(local_outcome.ai);
  1.1285 +	local_outcome.ai = NULL;
  1.1286 +
  1.1287 +	/* 1e. nodename is NULL (bind) */
  1.1288 +	memset(&hints, 0, sizeof(hints));
  1.1289 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1290 +	hints.ai_family = PF_UNSPEC;
  1.1291 +	hints.ai_socktype = SOCK_DGRAM;
  1.1292 +	hints.ai_flags = EVUTIL_AI_PASSIVE;
  1.1293 +	r = evdns_getaddrinfo(dns_base, NULL, "9090",
  1.1294 +	    &hints, gai_cb, &local_outcome);
  1.1295 +	tt_assert(!r);
  1.1296 +	tt_int_op(local_outcome.err,==,0);
  1.1297 +	tt_assert(local_outcome.ai);
  1.1298 +	/* we should get a v4 address of 0.0.0.0... */
  1.1299 +	a = ai_find_by_family(local_outcome.ai, PF_INET);
  1.1300 +	tt_assert(a);
  1.1301 +	test_ai_eq(a, "0.0.0.0:9090", SOCK_DGRAM, IPPROTO_UDP);
  1.1302 +	/* ... and a v6 address of ::0 */
  1.1303 +	a = ai_find_by_family(local_outcome.ai, PF_INET6);
  1.1304 +	tt_assert(a);
  1.1305 +	test_ai_eq(a, "[::]:9090", SOCK_DGRAM, IPPROTO_UDP);
  1.1306 +	evutil_freeaddrinfo(local_outcome.ai);
  1.1307 +	local_outcome.ai = NULL;
  1.1308 +
  1.1309 +	/* 1f. nodename is NULL (connect) */
  1.1310 +	memset(&hints, 0, sizeof(hints));
  1.1311 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1312 +	hints.ai_family = PF_UNSPEC;
  1.1313 +	hints.ai_socktype = SOCK_STREAM;
  1.1314 +	r = evdns_getaddrinfo(dns_base, NULL, "2",
  1.1315 +	    &hints, gai_cb, &local_outcome);
  1.1316 +	tt_assert(!r);
  1.1317 +	tt_int_op(local_outcome.err,==,0);
  1.1318 +	tt_assert(local_outcome.ai);
  1.1319 +	/* we should get a v4 address of 127.0.0.1 .... */
  1.1320 +	a = ai_find_by_family(local_outcome.ai, PF_INET);
  1.1321 +	tt_assert(a);
  1.1322 +	test_ai_eq(a, "127.0.0.1:2", SOCK_STREAM, IPPROTO_TCP);
  1.1323 +	/* ... and a v6 address of ::1 */
  1.1324 +	a = ai_find_by_family(local_outcome.ai, PF_INET6);
  1.1325 +	tt_assert(a);
  1.1326 +	test_ai_eq(a, "[::1]:2", SOCK_STREAM, IPPROTO_TCP);
  1.1327 +	evutil_freeaddrinfo(local_outcome.ai);
  1.1328 +	local_outcome.ai = NULL;
  1.1329 +
  1.1330 +	/* 1g. We find localhost immediately. (pf_unspec) */
  1.1331 +	memset(&hints, 0, sizeof(hints));
  1.1332 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1333 +	hints.ai_family = PF_UNSPEC;
  1.1334 +	hints.ai_socktype = SOCK_STREAM;
  1.1335 +	r = evdns_getaddrinfo(dns_base, "LOCALHOST", "80",
  1.1336 +	    &hints, gai_cb, &local_outcome);
  1.1337 +	tt_assert(!r);
  1.1338 +	tt_int_op(local_outcome.err,==,0);
  1.1339 +	tt_assert(local_outcome.ai);
  1.1340 +	/* we should get a v4 address of 127.0.0.1 .... */
  1.1341 +	a = ai_find_by_family(local_outcome.ai, PF_INET);
  1.1342 +	tt_assert(a);
  1.1343 +	test_ai_eq(a, "127.0.0.1:80", SOCK_STREAM, IPPROTO_TCP);
  1.1344 +	/* ... and a v6 address of ::1 */
  1.1345 +	a = ai_find_by_family(local_outcome.ai, PF_INET6);
  1.1346 +	tt_assert(a);
  1.1347 +	test_ai_eq(a, "[::1]:80", SOCK_STREAM, IPPROTO_TCP);
  1.1348 +	evutil_freeaddrinfo(local_outcome.ai);
  1.1349 +	local_outcome.ai = NULL;
  1.1350 +
  1.1351 +	/* 1g. We find localhost immediately. (pf_inet6) */
  1.1352 +	memset(&hints, 0, sizeof(hints));
  1.1353 +	memset(&local_outcome, 0, sizeof(local_outcome));
  1.1354 +	hints.ai_family = PF_INET6;
  1.1355 +	hints.ai_socktype = SOCK_STREAM;
  1.1356 +	r = evdns_getaddrinfo(dns_base, "LOCALHOST", "9999",
  1.1357 +	    &hints, gai_cb, &local_outcome);
  1.1358 +	tt_assert(! r);
  1.1359 +	tt_int_op(local_outcome.err,==,0);
  1.1360 +	tt_assert(local_outcome.ai);
  1.1361 +	a = local_outcome.ai;
  1.1362 +	test_ai_eq(a, "[::1]:9999", SOCK_STREAM, IPPROTO_TCP);
  1.1363 +	tt_ptr_op(a->ai_next, ==, NULL);
  1.1364 +	evutil_freeaddrinfo(local_outcome.ai);
  1.1365 +	local_outcome.ai = NULL;
  1.1366 +
  1.1367 +	/* 2. Okay, now we can actually test the asynchronous resolver. */
  1.1368 +	/* Start a dummy local dns server... */
  1.1369 +	port = regress_get_dnsserver(data->base, &dns_port, NULL,
  1.1370 +	    be_getaddrinfo_server_cb, &n_dns_questions);
  1.1371 +	tt_assert(port);
  1.1372 +	tt_int_op(dns_port, >=, 0);
  1.1373 +	/* ... and tell the evdns_base about it. */
  1.1374 +	evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", dns_port);
  1.1375 +	evdns_base_nameserver_ip_add(dns_base, buf);
  1.1376 +
  1.1377 +	memset(&hints, 0, sizeof(hints));
  1.1378 +	hints.ai_family = PF_UNSPEC;
  1.1379 +	hints.ai_socktype = SOCK_STREAM;
  1.1380 +	hints.ai_flags = EVUTIL_AI_CANONNAME;
  1.1381 +	/* 0: Request for both.example.com should return both addresses. */
  1.1382 +	r = evdns_getaddrinfo(dns_base, "both.example.com", "8000",
  1.1383 +	    &hints, gai_cb, &a_out[0]);
  1.1384 +	tt_assert(r);
  1.1385 +
  1.1386 +	/* 1: Request for v4only.example.com should return one address. */
  1.1387 +	r = evdns_getaddrinfo(dns_base, "v4only.example.com", "8001",
  1.1388 +	    &hints, gai_cb, &a_out[1]);
  1.1389 +	tt_assert(r);
  1.1390 +
  1.1391 +	/* 2: Request for v6only.example.com should return one address. */
  1.1392 +	hints.ai_flags = 0;
  1.1393 +	r = evdns_getaddrinfo(dns_base, "v6only.example.com", "8002",
  1.1394 +	    &hints, gai_cb, &a_out[2]);
  1.1395 +	tt_assert(r);
  1.1396 +
  1.1397 +	/* 3: PF_INET request for v4assert.example.com should not generate a
  1.1398 +	 * v6 request.	The server will fail the test if it does. */
  1.1399 +	hints.ai_family = PF_INET;
  1.1400 +	r = evdns_getaddrinfo(dns_base, "v4assert.example.com", "8003",
  1.1401 +	    &hints, gai_cb, &a_out[3]);
  1.1402 +	tt_assert(r);
  1.1403 +
  1.1404 +	/* 4: PF_INET6 request for v6assert.example.com should not generate a
  1.1405 +	 * v4 request.	The server will fail the test if it does. */
  1.1406 +	hints.ai_family = PF_INET6;
  1.1407 +	r = evdns_getaddrinfo(dns_base, "v6assert.example.com", "8004",
  1.1408 +	    &hints, gai_cb, &a_out[4]);
  1.1409 +	tt_assert(r);
  1.1410 +
  1.1411 +	/* 5: PF_INET request for nosuchplace.example.com should give NEXIST. */
  1.1412 +	hints.ai_family = PF_INET;
  1.1413 +	r = evdns_getaddrinfo(dns_base, "nosuchplace.example.com", "8005",
  1.1414 +	    &hints, gai_cb, &a_out[5]);
  1.1415 +	tt_assert(r);
  1.1416 +
  1.1417 +	/* 6: PF_UNSPEC request for nosuchplace.example.com should give NEXIST.
  1.1418 +	 */
  1.1419 +	hints.ai_family = PF_UNSPEC;
  1.1420 +	r = evdns_getaddrinfo(dns_base, "nosuchplace.example.com", "8006",
  1.1421 +	    &hints, gai_cb, &a_out[6]);
  1.1422 +	tt_assert(r);
  1.1423 +
  1.1424 +	/* 7: PF_UNSPEC request for v6timeout.example.com should give an ipv4
  1.1425 +	 * address only. */
  1.1426 +	hints.ai_family = PF_UNSPEC;
  1.1427 +	r = evdns_getaddrinfo(dns_base, "v6timeout.example.com", "8007",
  1.1428 +	    &hints, gai_cb, &a_out[7]);
  1.1429 +	tt_assert(r);
  1.1430 +
  1.1431 +	/* 8: PF_UNSPEC request for v6timeout-nonexist.example.com should give
  1.1432 +	 * a NEXIST */
  1.1433 +	hints.ai_family = PF_UNSPEC;
  1.1434 +	r = evdns_getaddrinfo(dns_base, "v6timeout-nonexist.example.com",
  1.1435 +	    "8008", &hints, gai_cb, &a_out[8]);
  1.1436 +	tt_assert(r);
  1.1437 +
  1.1438 +	/* 9: AI_ADDRCONFIG should at least not crash.	Can't test it more
  1.1439 +	 * without knowing what kind of internet we have. */
  1.1440 +	hints.ai_flags |= EVUTIL_AI_ADDRCONFIG;
  1.1441 +	r = evdns_getaddrinfo(dns_base, "both.example.com",
  1.1442 +	    "8009", &hints, gai_cb, &a_out[9]);
  1.1443 +	tt_assert(r);
  1.1444 +
  1.1445 +	/* 10: PF_UNSPEC for v4timeout.example.com should give an ipv6 address
  1.1446 +	 * only. */
  1.1447 +	hints.ai_family = PF_UNSPEC;
  1.1448 +	hints.ai_flags = 0;
  1.1449 +	r = evdns_getaddrinfo(dns_base, "v4timeout.example.com", "8010",
  1.1450 +	    &hints, gai_cb, &a_out[10]);
  1.1451 +	tt_assert(r);
  1.1452 +
  1.1453 +	/* 11: timeout.example.com: cancel it after 100 msec. */
  1.1454 +	r = evdns_getaddrinfo(dns_base, "all-timeout.example.com", "8011",
  1.1455 +	    &hints, gai_cb, &a_out[11]);
  1.1456 +	tt_assert(r);
  1.1457 +	{
  1.1458 +		struct timeval tv;
  1.1459 +		tv.tv_sec = 0;
  1.1460 +		tv.tv_usec = 100*1000; /* 100 msec */
  1.1461 +		event_base_once(data->base, -1, EV_TIMEOUT, cancel_gai_cb,
  1.1462 +		    r, &tv);
  1.1463 +	}
  1.1464 +
  1.1465 +	/* XXXXX There are more tests we could do, including:
  1.1466 +
  1.1467 +	   - A test to elicit NODATA.
  1.1468 +
  1.1469 +	 */
  1.1470 +
  1.1471 +	n_gai_results_pending = 12;
  1.1472 +	exit_base_on_no_pending_results = data->base;
  1.1473 +
  1.1474 +	event_base_dispatch(data->base);
  1.1475 +
  1.1476 +	/* 0: both.example.com */
  1.1477 +	tt_int_op(a_out[0].err, ==, 0);
  1.1478 +	tt_assert(a_out[0].ai);
  1.1479 +	tt_assert(a_out[0].ai->ai_next);
  1.1480 +	tt_assert(!a_out[0].ai->ai_next->ai_next);
  1.1481 +	a = ai_find_by_family(a_out[0].ai, PF_INET);
  1.1482 +	tt_assert(a);
  1.1483 +	test_ai_eq(a, "80.80.32.32:8000", SOCK_STREAM, IPPROTO_TCP);
  1.1484 +	a = ai_find_by_family(a_out[0].ai, PF_INET6);
  1.1485 +	tt_assert(a);
  1.1486 +	test_ai_eq(a, "[80ff::bbbb]:8000", SOCK_STREAM, IPPROTO_TCP);
  1.1487 +	tt_assert(a_out[0].ai->ai_canonname);
  1.1488 +	tt_str_op(a_out[0].ai->ai_canonname, ==, "both-canonical.example.com");
  1.1489 +
  1.1490 +	/* 1: v4only.example.com */
  1.1491 +	tt_int_op(a_out[1].err, ==, 0);
  1.1492 +	tt_assert(a_out[1].ai);
  1.1493 +	tt_assert(! a_out[1].ai->ai_next);
  1.1494 +	test_ai_eq(a_out[1].ai, "18.52.86.120:8001", SOCK_STREAM, IPPROTO_TCP);
  1.1495 +	tt_assert(a_out[1].ai->ai_canonname == NULL);
  1.1496 +
  1.1497 +
  1.1498 +	/* 2: v6only.example.com */
  1.1499 +	tt_int_op(a_out[2].err, ==, 0);
  1.1500 +	tt_assert(a_out[2].ai);
  1.1501 +	tt_assert(! a_out[2].ai->ai_next);
  1.1502 +	test_ai_eq(a_out[2].ai, "[b0b::f00d]:8002", SOCK_STREAM, IPPROTO_TCP);
  1.1503 +
  1.1504 +	/* 3: v4assert.example.com */
  1.1505 +	tt_int_op(a_out[3].err, ==, 0);
  1.1506 +	tt_assert(a_out[3].ai);
  1.1507 +	tt_assert(! a_out[3].ai->ai_next);
  1.1508 +	test_ai_eq(a_out[3].ai, "18.52.86.120:8003", SOCK_STREAM, IPPROTO_TCP);
  1.1509 +
  1.1510 +	/* 4: v6assert.example.com */
  1.1511 +	tt_int_op(a_out[4].err, ==, 0);
  1.1512 +	tt_assert(a_out[4].ai);
  1.1513 +	tt_assert(! a_out[4].ai->ai_next);
  1.1514 +	test_ai_eq(a_out[4].ai, "[b0b::f00d]:8004", SOCK_STREAM, IPPROTO_TCP);
  1.1515 +
  1.1516 +	/* 5: nosuchplace.example.com (inet) */
  1.1517 +	tt_int_op(a_out[5].err, ==, EVUTIL_EAI_NONAME);
  1.1518 +	tt_assert(! a_out[5].ai);
  1.1519 +
  1.1520 +	/* 6: nosuchplace.example.com (unspec) */
  1.1521 +	tt_int_op(a_out[6].err, ==, EVUTIL_EAI_NONAME);
  1.1522 +	tt_assert(! a_out[6].ai);
  1.1523 +
  1.1524 +	/* 7: v6timeout.example.com */
  1.1525 +	tt_int_op(a_out[7].err, ==, 0);
  1.1526 +	tt_assert(a_out[7].ai);
  1.1527 +	tt_assert(! a_out[7].ai->ai_next);
  1.1528 +	test_ai_eq(a_out[7].ai, "171.205.239.1:8007", SOCK_STREAM, IPPROTO_TCP);
  1.1529 +
  1.1530 +	/* 8: v6timeout-nonexist.example.com */
  1.1531 +	tt_int_op(a_out[8].err, ==, EVUTIL_EAI_NONAME);
  1.1532 +	tt_assert(! a_out[8].ai);
  1.1533 +
  1.1534 +	/* 9: both (ADDRCONFIG) */
  1.1535 +	tt_int_op(a_out[9].err, ==, 0);
  1.1536 +	tt_assert(a_out[9].ai);
  1.1537 +	a = ai_find_by_family(a_out[9].ai, PF_INET);
  1.1538 +	if (a)
  1.1539 +		test_ai_eq(a, "80.80.32.32:8009", SOCK_STREAM, IPPROTO_TCP);
  1.1540 +	else
  1.1541 +		tt_assert(ai_find_by_family(a_out[9].ai, PF_INET6));
  1.1542 +	a = ai_find_by_family(a_out[9].ai, PF_INET6);
  1.1543 +	if (a)
  1.1544 +		test_ai_eq(a, "[80ff::bbbb]:8009", SOCK_STREAM, IPPROTO_TCP);
  1.1545 +	else
  1.1546 +		tt_assert(ai_find_by_family(a_out[9].ai, PF_INET));
  1.1547 +
  1.1548 +	/* 10: v4timeout.example.com */
  1.1549 +	tt_int_op(a_out[10].err, ==, 0);
  1.1550 +	tt_assert(a_out[10].ai);
  1.1551 +	tt_assert(! a_out[10].ai->ai_next);
  1.1552 +	test_ai_eq(a_out[10].ai, "[a0a::ff01]:8010", SOCK_STREAM, IPPROTO_TCP);
  1.1553 +
  1.1554 +	/* 11: cancelled request. */
  1.1555 +	tt_int_op(a_out[11].err, ==, EVUTIL_EAI_CANCEL);
  1.1556 +	tt_assert(a_out[11].ai == NULL);
  1.1557 +
  1.1558 +end:
  1.1559 +	if (local_outcome.ai)
  1.1560 +		evutil_freeaddrinfo(local_outcome.ai);
  1.1561 +	for (i=0;i<10;++i) {
  1.1562 +		if (a_out[i].ai)
  1.1563 +			evutil_freeaddrinfo(a_out[i].ai);
  1.1564 +	}
  1.1565 +	if (port)
  1.1566 +		evdns_close_server_port(port);
  1.1567 +	if (dns_base)
  1.1568 +		evdns_base_free(dns_base, 0);
  1.1569 +}
  1.1570 +
  1.1571 +struct gaic_request_status {
  1.1572 +	int magic;
  1.1573 +	struct event_base *base;
  1.1574 +	struct evdns_base *dns_base;
  1.1575 +	struct evdns_getaddrinfo_request *request;
  1.1576 +	struct event cancel_event;
  1.1577 +	int canceled;
  1.1578 +};
  1.1579 +
  1.1580 +#define GAIC_MAGIC 0x1234abcd
  1.1581 +
  1.1582 +static int pending = 0;
  1.1583 +
  1.1584 +static void
  1.1585 +gaic_cancel_request_cb(evutil_socket_t fd, short what, void *arg)
  1.1586 +{
  1.1587 +	struct gaic_request_status *status = arg;
  1.1588 +
  1.1589 +	tt_assert(status->magic == GAIC_MAGIC);
  1.1590 +	status->canceled = 1;
  1.1591 +	evdns_getaddrinfo_cancel(status->request);
  1.1592 +	return;
  1.1593 +end:
  1.1594 +	event_base_loopexit(status->base, NULL);
  1.1595 +}
  1.1596 +
  1.1597 +static void
  1.1598 +gaic_server_cb(struct evdns_server_request *req, void *arg)
  1.1599 +{
  1.1600 +	ev_uint32_t answer = 0x7f000001;
  1.1601 +	tt_assert(req->nquestions);
  1.1602 +	evdns_server_request_add_a_reply(req, req->questions[0]->name, 1,
  1.1603 +	    &answer, 100);
  1.1604 +	evdns_server_request_respond(req, 0);
  1.1605 +	return;
  1.1606 +end:
  1.1607 +	evdns_server_request_respond(req, DNS_ERR_REFUSED);
  1.1608 +}
  1.1609 +
  1.1610 +
  1.1611 +static void
  1.1612 +gaic_getaddrinfo_cb(int result, struct evutil_addrinfo *res, void *arg)
  1.1613 +{
  1.1614 +	struct gaic_request_status *status = arg;
  1.1615 +	struct event_base *base = status->base;
  1.1616 +	tt_assert(status->magic == GAIC_MAGIC);
  1.1617 +
  1.1618 +	if (result == EVUTIL_EAI_CANCEL) {
  1.1619 +		tt_assert(status->canceled);
  1.1620 +	}
  1.1621 +	event_del(&status->cancel_event);
  1.1622 +
  1.1623 +	memset(status, 0xf0, sizeof(*status));
  1.1624 +	free(status);
  1.1625 +
  1.1626 +end:
  1.1627 +	if (--pending <= 0)
  1.1628 +		event_base_loopexit(base, NULL);
  1.1629 +}
  1.1630 +
  1.1631 +static void
  1.1632 +gaic_launch(struct event_base *base, struct evdns_base *dns_base)
  1.1633 +{
  1.1634 +	struct gaic_request_status *status = calloc(1,sizeof(*status));
  1.1635 +	struct timeval tv = { 0, 10000 };
  1.1636 +	status->magic = GAIC_MAGIC;
  1.1637 +	status->base = base;
  1.1638 +	status->dns_base = dns_base;
  1.1639 +	event_assign(&status->cancel_event, base, -1, 0, gaic_cancel_request_cb,
  1.1640 +	    status);
  1.1641 +	status->request = evdns_getaddrinfo(dns_base,
  1.1642 +	    "foobar.bazquux.example.com", "80", NULL, gaic_getaddrinfo_cb,
  1.1643 +	    status);
  1.1644 +	event_add(&status->cancel_event, &tv);
  1.1645 +	++pending;
  1.1646 +}
  1.1647 +
  1.1648 +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
  1.1649 +/* FIXME: We should move this to regress_main.c if anything else needs it.*/
  1.1650 +
  1.1651 +/* Trivial replacements for malloc/free/realloc to check for memory leaks.
  1.1652 + * Not threadsafe. */
  1.1653 +static int allocated_chunks = 0;
  1.1654 +
  1.1655 +static void *
  1.1656 +cnt_malloc(size_t sz)
  1.1657 +{
  1.1658 +	allocated_chunks += 1;
  1.1659 +	return malloc(sz);
  1.1660 +}
  1.1661 +
  1.1662 +static void *
  1.1663 +cnt_realloc(void *old, size_t sz)
  1.1664 +{
  1.1665 +	if (!old)
  1.1666 +		allocated_chunks += 1;
  1.1667 +	if (!sz)
  1.1668 +		allocated_chunks -= 1;
  1.1669 +	return realloc(old, sz);
  1.1670 +}
  1.1671 +
  1.1672 +static void
  1.1673 +cnt_free(void *ptr)
  1.1674 +{
  1.1675 +	allocated_chunks -= 1;
  1.1676 +	free(ptr);
  1.1677 +}
  1.1678 +
  1.1679 +struct testleak_env_t {
  1.1680 +	struct event_base *base;
  1.1681 +	struct evdns_base *dns_base;
  1.1682 +	struct evdns_request *req;
  1.1683 +	struct generic_dns_callback_result r;
  1.1684 +};
  1.1685 +
  1.1686 +static void *
  1.1687 +testleak_setup(const struct testcase_t *testcase)
  1.1688 +{
  1.1689 +	struct testleak_env_t *env;
  1.1690 +
  1.1691 +	allocated_chunks = 0;
  1.1692 +	event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free);
  1.1693 +	event_enable_debug_mode();
  1.1694 +
  1.1695 +	/* not mm_calloc: we don't want to mess with the count. */
  1.1696 +	env = calloc(1, sizeof(struct testleak_env_t));
  1.1697 +	env->base = event_base_new();
  1.1698 +	env->dns_base = evdns_base_new(env->base, 0);
  1.1699 +	env->req = evdns_base_resolve_ipv4(
  1.1700 +		env->dns_base, "example.com", DNS_QUERY_NO_SEARCH,
  1.1701 +		generic_dns_callback, &env->r);
  1.1702 +	return env;
  1.1703 +}
  1.1704 +
  1.1705 +static int
  1.1706 +testleak_cleanup(const struct testcase_t *testcase, void *env_)
  1.1707 +{
  1.1708 +	int ok = 0;
  1.1709 +	struct testleak_env_t *env = env_;
  1.1710 +	tt_assert(env);
  1.1711 +#ifdef _EVENT_DISABLE_DEBUG_MODE
  1.1712 +	tt_int_op(allocated_chunks, ==, 0);
  1.1713 +#else
  1.1714 +	/* FIXME: that's `1' because of event_debug_map_HT_GROW */
  1.1715 +	tt_int_op(allocated_chunks, ==, 1);
  1.1716 +#endif
  1.1717 +	ok = 1;
  1.1718 +end:
  1.1719 +	if (env) {
  1.1720 +		if (env->dns_base)
  1.1721 +			evdns_base_free(env->dns_base, 0);
  1.1722 +		if (env->base)
  1.1723 +			event_base_free(env->base);
  1.1724 +		free(env);
  1.1725 +	}
  1.1726 +	return ok;
  1.1727 +}
  1.1728 +
  1.1729 +static struct testcase_setup_t testleak_funcs = {
  1.1730 +	testleak_setup, testleak_cleanup
  1.1731 +};
  1.1732 +
  1.1733 +static void
  1.1734 +test_dbg_leak_cancel(void *env_)
  1.1735 +{
  1.1736 +	/* cancel, loop, free/dns, free/base */
  1.1737 +	struct testleak_env_t *env = env_;
  1.1738 +	int send_err_shutdown = 1;
  1.1739 +	evdns_cancel_request(env->dns_base, env->req);
  1.1740 +	env->req = 0;
  1.1741 +
  1.1742 +	/* `req` is freed in callback, that's why one loop is required. */
  1.1743 +	event_base_loop(env->base, EVLOOP_NONBLOCK);
  1.1744 +
  1.1745 +	/* send_err_shutdown means nothing as soon as our request is
  1.1746 +	 * already canceled */
  1.1747 +	evdns_base_free(env->dns_base, send_err_shutdown);
  1.1748 +	env->dns_base = 0;
  1.1749 +	event_base_free(env->base);
  1.1750 +	env->base = 0;
  1.1751 +}
  1.1752 +
  1.1753 +static void
  1.1754 +test_dbg_leak_shutdown(void *env_)
  1.1755 +{
  1.1756 +	/* free/dns, loop, free/base */
  1.1757 +	struct testleak_env_t *env = env_;
  1.1758 +	int send_err_shutdown = 1;
  1.1759 +
  1.1760 +	/* `req` is freed both with `send_err_shutdown` and without it,
  1.1761 +	 * the only difference is `evdns_callback` call */
  1.1762 +	env->req = 0;
  1.1763 +
  1.1764 +	evdns_base_free(env->dns_base, send_err_shutdown);
  1.1765 +	env->dns_base = 0;
  1.1766 +
  1.1767 +	/* `req` is freed in callback, that's why one loop is required */
  1.1768 +	event_base_loop(env->base, EVLOOP_NONBLOCK);
  1.1769 +	event_base_free(env->base);
  1.1770 +	env->base = 0;
  1.1771 +}
  1.1772 +#endif
  1.1773 +
  1.1774 +static void
  1.1775 +test_getaddrinfo_async_cancel_stress(void *ptr)
  1.1776 +{
  1.1777 +	struct event_base *base;
  1.1778 +	struct evdns_base *dns_base = NULL;
  1.1779 +	struct evdns_server_port *server = NULL;
  1.1780 +	evutil_socket_t fd = -1;
  1.1781 +	struct sockaddr_in sin;
  1.1782 +	struct sockaddr_storage ss;
  1.1783 +	ev_socklen_t slen;
  1.1784 +	int i;
  1.1785 +
  1.1786 +	base = event_base_new();
  1.1787 +	dns_base = evdns_base_new(base, 0);
  1.1788 +
  1.1789 +	memset(&sin, 0, sizeof(sin));
  1.1790 +	sin.sin_family = AF_INET;
  1.1791 +	sin.sin_port = 0;
  1.1792 +	sin.sin_addr.s_addr = htonl(0x7f000001);
  1.1793 +	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  1.1794 +		tt_abort_perror("socket");
  1.1795 +	}
  1.1796 +	evutil_make_socket_nonblocking(fd);
  1.1797 +	if (bind(fd, (struct sockaddr*)&sin, sizeof(sin))<0) {
  1.1798 +		tt_abort_perror("bind");
  1.1799 +	}
  1.1800 +	server = evdns_add_server_port_with_base(base, fd, 0, gaic_server_cb,
  1.1801 +	    base);
  1.1802 +
  1.1803 +	memset(&ss, 0, sizeof(ss));
  1.1804 +	slen = sizeof(ss);
  1.1805 +	if (getsockname(fd, (struct sockaddr*)&ss, &slen)<0) {
  1.1806 +		tt_abort_perror("getsockname");
  1.1807 +	}
  1.1808 +	evdns_base_nameserver_sockaddr_add(dns_base,
  1.1809 +	    (struct sockaddr*)&ss, slen, 0);
  1.1810 +
  1.1811 +	for (i = 0; i < 1000; ++i) {
  1.1812 +		gaic_launch(base, dns_base);
  1.1813 +	}
  1.1814 +
  1.1815 +	event_base_dispatch(base);
  1.1816 +
  1.1817 +end:
  1.1818 +	if (dns_base)
  1.1819 +		evdns_base_free(dns_base, 1);
  1.1820 +	if (server)
  1.1821 +		evdns_close_server_port(server);
  1.1822 +	if (fd >= 0)
  1.1823 +		evutil_closesocket(fd);
  1.1824 +}
  1.1825 +
  1.1826 +
  1.1827 +#define DNS_LEGACY(name, flags)					       \
  1.1828 +	{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup,   \
  1.1829 +		    dns_##name }
  1.1830 +
  1.1831 +struct testcase_t dns_testcases[] = {
  1.1832 +	DNS_LEGACY(server, TT_FORK|TT_NEED_BASE),
  1.1833 +	DNS_LEGACY(gethostbyname, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
  1.1834 +	DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
  1.1835 +	DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
  1.1836 +	{ "resolve_reverse", dns_resolve_reverse, TT_FORK, NULL, NULL },
  1.1837 +	{ "search", dns_search_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
  1.1838 +	{ "search_cancel", dns_search_cancel_test,
  1.1839 +	  TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
  1.1840 +	{ "retry", dns_retry_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
  1.1841 +	{ "reissue", dns_reissue_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
  1.1842 +	{ "inflight", dns_inflight_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
  1.1843 +	{ "bufferevent_connect_hostname", test_bufferevent_connect_hostname,
  1.1844 +	  TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
  1.1845 +
  1.1846 +	{ "getaddrinfo_async", test_getaddrinfo_async,
  1.1847 +	  TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" },
  1.1848 +	{ "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress,
  1.1849 +	  TT_FORK, NULL, NULL },
  1.1850 +
  1.1851 +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
  1.1852 +	{ "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL },
  1.1853 +	{ "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL },
  1.1854 +#endif
  1.1855 +
  1.1856 +	END_OF_TESTCASES
  1.1857 +};
  1.1858 +

mercurial