1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu> 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * All rights reserved. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Redistribution and use in source and binary forms, with or without 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * modification, are permitted provided that the following conditions 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * are met: 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1. Redistributions of source code must retain the above copyright 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * notice, this list of conditions and the following disclaimer. 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 2. Redistributions in binary form must reproduce the above copyright 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * notice, this list of conditions and the following disclaimer in the 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * documentation and/or other materials provided with the distribution. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 3. The name of the author may not be used to endorse or promote products 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * derived from this software without specific prior written permission. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <winsock2.h> 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <windows.h> 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_CONFIG_H 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "config.h" 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/types.h> 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/stat.h> 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_SYS_TIME_H 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/time.h> 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/queue.h> 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef WIN32 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/socket.h> 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <signal.h> 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <netinet/in.h> 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <arpa/inet.h> 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h> 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_NETINET_IN6_H 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <netinet/in6.h> 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef HAVE_NETDB_H 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <netdb.h> 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <fcntl.h> 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h> 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h> 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h> 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "event.h" 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "evdns.h" 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "log.h" 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int dns_ok = 0; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int dns_err = 0; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid dns_suite(void); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_gethostbyname_cb(int result, char type, int count, int ttl, 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void *addresses, void *arg) 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = dns_err = 0; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result == DNS_ERR_TIMEOUT) { 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "[Timed out] "); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_err = result; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result != DNS_ERR_NONE) { 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "[Error code %d] ", result); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "type: %d, count: %d, ttl: %d: ", type, count, ttl); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (type) { 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DNS_IPv6_AAAA: { 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in6_addr *in6_addrs = addresses; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char buf[INET6_ADDRSTRLEN+1]; 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* a resolution that's not valid does not help */ 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ttl < 0) 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < count; ++i) { 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *b = inet_ntop(AF_INET6, &in6_addrs[i], buf,sizeof(buf)); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (b) 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "%s ", b); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "%s ", strerror(errno)); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DNS_IPv4_A: { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in_addr *in_addrs = addresses; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i; 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* a resolution that's not valid does not help */ 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ttl < 0) 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < count; ++i) 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "%s ", inet_ntoa(in_addrs[i])); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DNS_PTR: 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* may get at most one PTR */ 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (count != 1) 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stderr, "%s ", *(char **)addresses); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = type; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottout: 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_gethostbyname(void) 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Simple DNS resolve: "); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_resolve_ipv4("www.monkey.org", 0, dns_gethostbyname_cb, NULL); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dns_ok == DNS_IPv4_A) { 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_gethostbyname6(void) 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "IPv6 DNS resolve: "); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_resolve_ipv6("www.ietf.org", 0, dns_gethostbyname_cb, NULL); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dns_ok == DNS_IPv6_AAAA) { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) { 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "SKIPPED\n"); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED (%d)\n", dns_ok); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_gethostbyaddr(void) 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in_addr in; 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */ 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Simple reverse DNS resolve: "); 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_resolve_reverse(&in, 0, dns_gethostbyname_cb, NULL); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dns_ok == DNS_PTR) { 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int n_server_responses = 0; 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_server_request_cb(struct evdns_server_request *req, void *data) 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int i, r; 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa"; 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = 0; i < req->nquestions; ++i) { 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in_addr ans; 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (req->questions[i]->type == EVDNS_TYPE_A && 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->questions[i]->dns_question_class == EVDNS_CLASS_INET && 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !strcmp(req->questions[i]->name, "zz.example.com")) { 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott r = evdns_server_request_add_a_reply(req, "zz.example.com", 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1, &ans.s_addr, 12345); 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (r<0) 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (req->questions[i]->type == EVDNS_TYPE_AAAA && 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->questions[i]->dns_question_class == EVDNS_CLASS_INET && 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !strcmp(req->questions[i]->name, "zz.example.com")) { 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char addr6[17] = "abcdefghijklmnop"; 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott r = evdns_server_request_add_aaaa_reply(req, "zz.example.com", 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1, addr6, 123); 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (r<0) 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (req->questions[i]->type == EVDNS_TYPE_PTR && 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->questions[i]->dns_question_class == EVDNS_CLASS_INET && 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !strcmp(req->questions[i]->name, TEST_ARPA)) { 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott r = evdns_server_request_add_ptr_reply(req, NULL, TEST_ARPA, 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "ZZ.EXAMPLE.COM", 54321); 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (r<0) 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Unexpected question %d %d \"%s\" ", 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->questions[i]->type, 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->questions[i]->dns_question_class, 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott req->questions[i]->name); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott r = evdns_server_request_respond(req, 0); 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (r<0) { 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Couldn't send reply. "); 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_server_gethostbyname_cb(int result, char type, int count, int ttl, 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void *addresses, void *arg) 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result != DNS_ERR_NONE) { 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Unexpected result %d. ", result); 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (count != 1) { 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Unexpected answer count %d. ", count); 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (type) { 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DNS_IPv4_A: { 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in_addr *in_addrs = addresses; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (in_addrs[0].s_addr != htonl(0xc0a80b0bUL) || ttl != 12345) { 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Bad IPv4 response \"%s\" %d. ", 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott inet_ntoa(in_addrs[0]), ttl); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DNS_IPv6_AAAA: { 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined (HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in6_addr *in6_addrs = addresses; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char buf[INET6_ADDRSTRLEN+1]; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memcmp(&in6_addrs[0].s6_addr, "abcdefghijklmnop", 16) 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott || ttl != 123) { 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char *b = inet_ntop(AF_INET6, &in6_addrs[0],buf,sizeof(buf)); 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Bad IPv6 response \"%s\" %d. ", b, ttl); 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DNS_PTR: { 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char **addrs = addresses; 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (strcmp(addrs[0], "ZZ.EXAMPLE.COM") || ttl != 54321) { 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Bad PTR response \"%s\" %d. ", 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott addrs[0], ttl); 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott goto out; 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Bad response type %d. ", type); 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 0; 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out: 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (++n_server_responses == 3) { 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_loopexit(NULL); 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_server(void) 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int sock; 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct sockaddr_in my_addr; 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct evdns_server_port *port; 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct in_addr resolve_addr; 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_ok = 1; 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "DNS server support: "); 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Add ourself as the only nameserver, and make sure we really are 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the only nameserver. */ 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_nameserver_ip_add("127.0.0.1:35353"); 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (evdns_count_nameservers() != 1) { 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "Couldn't set up.\n"); 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Now configure a nameserver port. */ 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sock = socket(AF_INET, SOCK_DGRAM, 0); 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sock == -1) { 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott perror("socket"); 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott u_long nonblocking = 1; 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ioctlsocket(sock, FIONBIO, &nonblocking); 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fcntl(sock, F_SETFL, O_NONBLOCK); 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&my_addr, 0, sizeof(my_addr)); 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott my_addr.sin_family = AF_INET; 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott my_addr.sin_port = htons(35353); 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott my_addr.sin_addr.s_addr = htonl(0x7f000001UL); 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott perror("bind"); 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit (1); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL); 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Send two queries. */ 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_resolve_ipv4("zz.example.com", DNS_QUERY_NO_SEARCH, 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_server_gethostbyname_cb, NULL); 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_resolve_ipv6("zz.example.com", DNS_QUERY_NO_SEARCH, 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_server_gethostbyname_cb, NULL); 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_resolve_reverse(&resolve_addr, 0, 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_server_gethostbyname_cb, NULL); 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_dispatch(); 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dns_ok) { 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "OK\n"); 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott fprintf(stdout, "FAILED\n"); 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott exit(1); 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_close_server_port(port); 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_shutdown(0); /* remove ourself as nameserver. */ 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef WIN32 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott closesocket(sock); 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott close(sock); 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdns_suite(void) 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{ 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_server(); /* Do this before we call evdns_init. */ 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_init(); 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_gethostbyname(); 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_gethostbyname6(); 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dns_gethostbyaddr(); 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott evdns_shutdown(0); 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 377