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