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