resolv_test.c revision 243346
1122394Sharti/* $NetBSD: resolv.c,v 1.6 2004/05/23 16:59:11 christos Exp $ */ 2122394Sharti 3122394Sharti/*- 4122394Sharti * Copyright (c) 2004 The NetBSD Foundation, Inc. 5122394Sharti * All rights reserved. 6122394Sharti * 7310901Sngie * This code is derived from software contributed to The NetBSD Foundation 8133211Sharti * by Christos Zoulas. 9133211Sharti * 10133211Sharti * Redistribution and use in source and binary forms, with or without 11133211Sharti * modification, are permitted provided that the following conditions 12133211Sharti * are met: 13122394Sharti * 1. Redistributions of source code must retain the above copyright 14122394Sharti * notice, this list of conditions and the following disclaimer. 15122394Sharti * 2. Redistributions in binary form must reproduce the above copyright 16310901Sngie * notice, this list of conditions and the following disclaimer in the 17133211Sharti * documentation and/or other materials provided with the distribution. 18133211Sharti * 19133211Sharti * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20133211Sharti * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21133211Sharti * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22133211Sharti * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23133211Sharti * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24133211Sharti * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25133211Sharti * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26133211Sharti * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27133211Sharti * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28122394Sharti * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29156066Sharti * POSSIBILITY OF SUCH DAMAGE. 30122394Sharti */ 31122394Sharti/* $FreeBSD: head/tools/regression/lib/libc/resolv/resolv.c 243346 2012-11-20 19:23:44Z emaste $ */ 32122394Sharti#include <sys/cdefs.h> 33122394Sharti__RCSID("$NetBSD: resolv.c,v 1.6 2004/05/23 16:59:11 christos Exp $"); 34122394Sharti 35122394Sharti#include <sys/types.h> 36122394Sharti#include <sys/socket.h> 37122394Sharti#include <pthread.h> 38150920Sharti#include <stdio.h> 39133211Sharti#include <netdb.h> 40150920Sharti#include <stdlib.h> 41150920Sharti#include <unistd.h> 42150920Sharti#include <err.h> 43122394Sharti#include <string.h> 44156066Sharti#include <stringlist.h> 45156066Sharti 46122394Sharti#define NTHREADS 10 47122394Sharti#define NHOSTS 100 48122394Sharti#define WS " \t\n\r" 49122394Sharti 50122394Shartienum method { 51122394Sharti METHOD_GETADDRINFO, 52122394Sharti METHOD_GETHOSTBY, 53122394Sharti METHOD_GETIPNODEBY 54122394Sharti}; 55122394Sharti 56122394Shartistatic StringList *hosts = NULL; 57122394Shartistatic int debug = 0; 58122394Shartistatic enum method method = METHOD_GETADDRINFO; 59122394Shartistatic int reverse = 0; 60122394Shartistatic int *ask = NULL; 61122394Shartistatic int *got = NULL; 62122394Sharti 63122394Shartistatic void usage(void) __attribute__((__noreturn__)); 64122394Shartistatic void load(const char *); 65122394Shartistatic void resolvone(int); 66122394Shartistatic void *resolvloop(void *); 67122394Shartistatic void run(int *); 68122394Sharti 69122394Shartistatic pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER; 70122394Sharti 71122394Shartistatic void 72122394Shartiusage(void) 73122394Sharti{ 74122394Sharti (void)fprintf(stderr, 75122394Sharti "Usage: %s [-AdHIr] [-h <nhosts>] [-n <nthreads>] <file> ...\n", 76122394Sharti getprogname()); 77122394Sharti exit(1); 78122394Sharti} 79122394Sharti 80122394Shartistatic void 81122394Shartiload(const char *fname) 82122394Sharti{ 83122394Sharti FILE *fp; 84122394Sharti size_t len; 85122394Sharti char *line; 86122394Sharti 87122394Sharti if ((fp = fopen(fname, "r")) == NULL) 88122394Sharti err(1, "Cannot open `%s'", fname); 89122394Sharti while ((line = fgetln(fp, &len)) != NULL) { 90122394Sharti char c = line[len]; 91122394Sharti char *ptr; 92122394Sharti line[len] = '\0'; 93122394Sharti for (ptr = strtok(line, WS); ptr; ptr = strtok(NULL, WS)) 94122394Sharti sl_add(hosts, strdup(ptr)); 95122394Sharti line[len] = c; 96122394Sharti } 97122394Sharti 98122394Sharti (void)fclose(fp); 99122394Sharti} 100122394Sharti 101122394Shartistatic int 102122394Shartiresolv_getaddrinfo(pthread_t self, char *host, int port) 103350638Semaste{ 104350638Semaste char portstr[6], buf[1024], hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; 105350638Semaste struct addrinfo hints, *res; 106350638Semaste int error, len; 107350638Semaste 108122394Sharti snprintf(portstr, sizeof(portstr), "%d", port); 109122394Sharti memset(&hints, 0, sizeof(hints)); 110122394Sharti hints.ai_family = AF_UNSPEC; 111122394Sharti hints.ai_flags = AI_PASSIVE; 112122394Sharti hints.ai_socktype = SOCK_STREAM; 113122394Sharti error = getaddrinfo(host, portstr, &hints, &res); 114122394Sharti if (debug) { 115122394Sharti len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", 116122394Sharti self, host, error ? "not found" : "ok"); 117122394Sharti (void)write(STDOUT_FILENO, buf, len); 118122394Sharti } 119122394Sharti if (error == 0 && reverse) { 120122394Sharti memset(hbuf, 0, sizeof(hbuf)); 121122394Sharti memset(pbuf, 0, sizeof(pbuf)); 122122394Sharti getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), 123122394Sharti pbuf, sizeof(pbuf), 0); 124122394Sharti if (debug) { 125122394Sharti len = snprintf(buf, sizeof(buf), 126122394Sharti "%p: reverse %s %s\n", self, hbuf, pbuf); 127122394Sharti (void)write(STDOUT_FILENO, buf, len); 128122394Sharti } 129122394Sharti } 130122394Sharti if (error == 0) 131122394Sharti freeaddrinfo(res); 132122394Sharti return error; 133122394Sharti} 134122394Sharti 135122394Shartistatic int 136122394Shartiresolv_gethostby(pthread_t self, char *host) 137122394Sharti{ 138122394Sharti char buf[1024]; 139122394Sharti struct hostent *hp, *hp2; 140122394Sharti int len; 141122394Sharti 142122394Sharti hp = gethostbyname(host); 143122394Sharti if (debug) { 144122394Sharti len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", 145122394Sharti self, host, (hp == NULL) ? "not found" : "ok"); 146122394Sharti (void)write(STDOUT_FILENO, buf, len); 147122394Sharti } 148122394Sharti if (hp && reverse) { 149122394Sharti memcpy(buf, hp->h_addr, hp->h_length); 150122394Sharti hp2 = gethostbyaddr(buf, hp->h_length, hp->h_addrtype); 151122394Sharti if (hp2 && debug) { 152122394Sharti len = snprintf(buf, sizeof(buf), 153122394Sharti "%p: reverse %s\n", self, hp2->h_name); 154122394Sharti (void)write(STDOUT_FILENO, buf, len); 155122394Sharti } 156122394Sharti } 157122394Sharti return hp ? 0 : -1; 158122394Sharti} 159122394Sharti 160122394Shartistatic int 161122394Shartiresolv_getipnodeby(pthread_t self, char *host) 162122394Sharti{ 163122394Sharti char buf[1024]; 164122394Sharti struct hostent *hp, *hp2; 165122394Sharti int len, h_error; 166122394Sharti 167122394Sharti hp = getipnodebyname(host, AF_INET, 0, &h_error); 168122394Sharti if (debug) { 169122394Sharti len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", 170122394Sharti self, host, (hp == NULL) ? "not found" : "ok"); 171122394Sharti (void)write(STDOUT_FILENO, buf, len); 172122394Sharti } 173122394Sharti if (hp && reverse) { 174122394Sharti memcpy(buf, hp->h_addr, hp->h_length); 175122394Sharti hp2 = getipnodebyaddr(buf, hp->h_length, hp->h_addrtype, 176122394Sharti &h_error); 177122394Sharti if (hp2 && debug) { 178122394Sharti len = snprintf(buf, sizeof(buf), 179122394Sharti "%p: reverse %s\n", self, hp2->h_name); 180122394Sharti (void)write(STDOUT_FILENO, buf, len); 181122394Sharti } 182122394Sharti if (hp2) 183122394Sharti freehostent(hp2); 184122394Sharti } 185122394Sharti if (hp) 186122394Sharti freehostent(hp); 187122394Sharti return hp ? 0 : -1; 188122394Sharti} 189122394Sharti 190122394Shartistatic void 191122394Shartiresolvone(int n) 192122394Sharti{ 193122394Sharti char buf[1024]; 194122394Sharti pthread_t self = pthread_self(); 195122394Sharti size_t i = (random() & 0x0fffffff) % hosts->sl_cur; 196122394Sharti char *host = hosts->sl_str[i]; 197122394Sharti struct addrinfo hints, *res; 198122394Sharti int error, len; 199122394Sharti 200122394Sharti if (debug) { 201122394Sharti len = snprintf(buf, sizeof(buf), "%p: %d resolving %s %d\n", 202122394Sharti self, n, host, (int)i); 203122394Sharti (void)write(STDOUT_FILENO, buf, len); 204216294Ssyrinx } 205122394Sharti switch (method) { 206122394Sharti case METHOD_GETADDRINFO: 207122394Sharti error = resolv_getaddrinfo(self, host, i); 208122394Sharti break; 209122394Sharti case METHOD_GETHOSTBY: 210122394Sharti error = resolv_gethostby(self, host); 211122394Sharti break; 212122394Sharti case METHOD_GETIPNODEBY: 213122394Sharti error = resolv_getipnodeby(self, host); 214122394Sharti break; 215122394Sharti default: 216122394Sharti break; 217122394Sharti } 218122394Sharti pthread_mutex_lock(&stats); 219122394Sharti ask[i]++; 220122394Sharti got[i] += error == 0; 221122394Sharti pthread_mutex_unlock(&stats); 222122394Sharti} 223216294Ssyrinx 224216294Ssyrinxstatic void * 225122394Shartiresolvloop(void *p) 226122394Sharti{ 227122394Sharti int *nhosts = (int *)p; 228122394Sharti if (*nhosts == 0) 229122394Sharti return NULL; 230122394Sharti do 231122394Sharti resolvone(*nhosts); 232122394Sharti while (--(*nhosts)); 233122394Sharti return NULL; 234122394Sharti} 235122394Sharti 236122394Shartistatic void 237122394Shartirun(int *nhosts) 238122394Sharti{ 239122394Sharti pthread_t self = pthread_self(); 240133211Sharti if (pthread_create(&self, NULL, resolvloop, nhosts) != 0) 241122394Sharti err(1, "pthread_create"); 242122394Sharti} 243122394Sharti 244122394Shartiint 245122394Shartimain(int argc, char *argv[]) 246122394Sharti{ 247122394Sharti int nthreads = NTHREADS; 248122394Sharti int nhosts = NHOSTS; 249122394Sharti int i, c, done, *nleft; 250122394Sharti hosts = sl_init(); 251122394Sharti 252122394Sharti srandom(1234); 253122394Sharti 254122394Sharti while ((c = getopt(argc, argv, "Adh:HIn:r")) != -1) 255122394Sharti switch (c) { 256124861Sharti case 'A': 257124861Sharti method = METHOD_GETADDRINFO; 258124861Sharti break; 259124861Sharti case 'd': 260124861Sharti debug++; 261124861Sharti break; 262124861Sharti case 'h': 263122394Sharti nhosts = atoi(optarg); 264122394Sharti break; 265122394Sharti case 'H': 266122394Sharti method = METHOD_GETHOSTBY; 267122394Sharti break; 268122394Sharti case 'I': 269122394Sharti method = METHOD_GETIPNODEBY; 270122394Sharti break; 271122394Sharti case 'n': 272122394Sharti nthreads = atoi(optarg); 273122394Sharti break; 274122394Sharti case 'r': 275122394Sharti reverse++; 276122394Sharti break; 277122394Sharti default: 278122394Sharti usage(); 279122394Sharti } 280122394Sharti 281122394Sharti for (i = optind; i < argc; i++) 282122394Sharti load(argv[i]); 283122394Sharti 284122394Sharti if (hosts->sl_cur == 0) 285122394Sharti usage(); 286122394Sharti 287122394Sharti if ((nleft = malloc(nthreads * sizeof(int))) == NULL) 288122394Sharti err(1, "malloc"); 289133211Sharti if ((ask = calloc(hosts->sl_cur, sizeof(int))) == NULL) 290122394Sharti err(1, "calloc"); 291122394Sharti if ((got = calloc(hosts->sl_cur, sizeof(int))) == NULL) 292122394Sharti err(1, "calloc"); 293310901Sngie 294122394Sharti 295133211Sharti for (i = 0; i < nthreads; i++) { 296122394Sharti nleft[i] = nhosts; 297122394Sharti run(&nleft[i]); 298133211Sharti } 299122394Sharti 300122394Sharti for (done = 0; !done;) { 301122394Sharti done = 1; 302122394Sharti for (i = 0; i < nthreads; i++) { 303122394Sharti if (nleft[i] != 0) { 304122394Sharti done = 0; 305122394Sharti break; 306122394Sharti } 307122394Sharti } 308122394Sharti sleep(1); 309122394Sharti } 310122394Sharti c = 0; 311122394Sharti for (i = 0; i < hosts->sl_cur; i++) { 312122394Sharti if (ask[i] != got[i] && got[i] != 0) { 313122394Sharti warnx("Error: host %s ask %d got %d\n", 314122394Sharti hosts->sl_str[i], ask[i], got[i]); 315122394Sharti c++; 316122394Sharti } 317122394Sharti } 318122394Sharti free(nleft); 319122394Sharti free(ask); 320122394Sharti free(got); 321122394Sharti sl_free(hosts, 1); 322122394Sharti return c; 323122394Sharti} 324122394Sharti