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