resolv_test.c revision 145857
1/* $NetBSD: resolv.c,v 1.6 2004/05/23 16:59:11 christos Exp $ */ 2 3/*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38#include <sys/cdefs.h> 39__RCSID("$NetBSD: resolv.c,v 1.6 2004/05/23 16:59:11 christos Exp $"); 40 41#include <pthread.h> 42#include <stdio.h> 43#include <netdb.h> 44#include <stdlib.h> 45#include <unistd.h> 46#include <err.h> 47#include <string.h> 48#include <stringlist.h> 49 50#define NTHREADS 10 51#define NHOSTS 100 52#define WS " \t\n\r" 53 54static StringList *hosts = NULL; 55static int debug = 0; 56static int *ask = NULL; 57static int *got = NULL; 58 59static void usage(void) __attribute__((__noreturn__)); 60static void load(const char *); 61static void resolvone(int); 62static void *resolvloop(void *); 63static void run(int *); 64 65static pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER; 66 67static void 68usage(void) 69{ 70 (void)fprintf(stderr, 71 "Usage: %s [-d] [-h <nhosts>] [-n <nthreads>] <file> ...\n", 72 getprogname()); 73 exit(1); 74} 75 76static void 77load(const char *fname) 78{ 79 FILE *fp; 80 size_t len; 81 char *line; 82 83 if ((fp = fopen(fname, "r")) == NULL) 84 err(1, "Cannot open `%s'", fname); 85 while ((line = fgetln(fp, &len)) != NULL) { 86 char c = line[len]; 87 char *ptr; 88 line[len] = '\0'; 89 for (ptr = strtok(line, WS); ptr; ptr = strtok(NULL, WS)) 90 sl_add(hosts, strdup(ptr)); 91 line[len] = c; 92 } 93 94 (void)fclose(fp); 95} 96 97static void 98resolvone(int n) 99{ 100 char buf[1024]; 101 pthread_t self = pthread_self(); 102 size_t i = (random() & 0x0fffffff) % hosts->sl_cur; 103 char *host = hosts->sl_str[i]; 104 struct addrinfo *res; 105 int error, len; 106 if (debug) { 107 len = snprintf(buf, sizeof(buf), "%p: %d resolving %s %d\n", 108 self, n, host, (int)i); 109 (void)write(STDOUT_FILENO, buf, len); 110 } 111 error = getaddrinfo(host, NULL, NULL, &res); 112 if (debug) { 113 len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", 114 self, host, error ? "not found" : "ok"); 115 (void)write(STDOUT_FILENO, buf, len); 116 } 117 pthread_mutex_lock(&stats); 118 ask[i]++; 119 got[i] += error == 0; 120 pthread_mutex_unlock(&stats); 121 if (error == 0) 122 freeaddrinfo(res); 123} 124 125static void * 126resolvloop(void *p) 127{ 128 int *nhosts = (int *)p; 129 if (*nhosts == 0) 130 return; 131 do 132 resolvone(*nhosts); 133 while (--(*nhosts)); 134 return NULL; 135} 136 137static void 138run(int *nhosts) 139{ 140 pthread_t self = pthread_self(); 141 if (pthread_create(&self, NULL, resolvloop, nhosts) != 0) 142 err(1, "pthread_create"); 143} 144 145int 146main(int argc, char *argv[]) 147{ 148 int nthreads = NTHREADS; 149 int nhosts = NHOSTS; 150 int i, c, done, *nleft; 151 hosts = sl_init(); 152 153 srandom(1234); 154 155 while ((c = getopt(argc, argv, "dh:n:")) != -1) 156 switch (c) { 157 case 'd': 158 debug++; 159 break; 160 case 'h': 161 nhosts = atoi(optarg); 162 break; 163 case 'n': 164 nthreads = atoi(optarg); 165 break; 166 default: 167 usage(); 168 } 169 170 for (i = optind; i < argc; i++) 171 load(argv[i]); 172 173 if (hosts->sl_cur == 0) 174 usage(); 175 176 if ((nleft = malloc(nthreads * sizeof(int))) == NULL) 177 err(1, "malloc"); 178 if ((ask = calloc(hosts->sl_cur, sizeof(int))) == NULL) 179 err(1, "calloc"); 180 if ((got = calloc(hosts->sl_cur, sizeof(int))) == NULL) 181 err(1, "calloc"); 182 183 184 for (i = 0; i < nthreads; i++) { 185 nleft[i] = nhosts; 186 run(&nleft[i]); 187 } 188 189 for (done = 0; !done;) { 190 done = 1; 191 for (i = 0; i < nthreads; i++) { 192 if (nleft[i] != 0) { 193 done = 0; 194 break; 195 } 196 } 197 sleep(1); 198 } 199 c = 0; 200 for (i = 0; i < hosts->sl_cur; i++) { 201 if (ask[i] != got[i] && got[i] != 0) { 202 warnx("Error: host %s ask %d got %d\n", 203 hosts->sl_str[i], ask[i], got[i]); 204 c++; 205 } 206 } 207 free(nleft); 208 free(ask); 209 free(got); 210 sl_free(hosts, 1); 211 return c; 212} 213