1 /* $NetBSD: byname_test.c,v 1.7 2014/12/10 04:37:53 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 2000, 2001 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: byname_test.c,v 1.33 2009/09/02 23:48:01 tbox Exp */ 21 22 /*! \file 23 * \author 24 * Principal Author: Bob Halley 25 */ 26 27 #include <config.h> 28 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include <isc/app.h> 33 #include <isc/commandline.h> 34 #include <isc/entropy.h> 35 #include <isc/hash.h> 36 #include <isc/netaddr.h> 37 #include <isc/task.h> 38 #include <isc/timer.h> 39 #include <isc/util.h> 40 41 #include <dns/adb.h> 42 #include <dns/cache.h> 43 #include <dns/dispatch.h> 44 #include <dns/events.h> 45 #include <dns/forward.h> 46 #include <dns/log.h> 47 #include <dns/resolver.h> 48 #include <dns/result.h> 49 50 static isc_mem_t *mctx = NULL; 51 static isc_entropy_t *ectx = NULL; 52 static isc_taskmgr_t *taskmgr; 53 static dns_view_t *view = NULL; 54 static dns_adbfind_t *find = NULL; 55 static isc_task_t *task = NULL; 56 static dns_fixedname_t name; 57 static dns_fixedname_t target; 58 static isc_log_t *lctx; 59 static isc_logconfig_t *lcfg; 60 static unsigned int level = 0; 61 62 static void adb_callback(isc_task_t *task, isc_event_t *event); 63 64 static void 65 log_init(void) { 66 isc_logdestination_t destination; 67 unsigned int flags; 68 69 /* 70 * Setup a logging context. 71 */ 72 RUNTIME_CHECK(isc_log_create(mctx, &lctx, &lcfg) == ISC_R_SUCCESS); 73 isc_log_setcontext(lctx); 74 dns_log_init(lctx); 75 dns_log_setcontext(lctx); 76 77 /* 78 * Create and install the default channel. 79 */ 80 destination.file.stream = stderr; 81 destination.file.name = NULL; 82 destination.file.versions = ISC_LOG_ROLLNEVER; 83 destination.file.maximum_size = 0; 84 flags = ISC_LOG_PRINTTIME; 85 RUNTIME_CHECK(isc_log_createchannel(lcfg, "_default", 86 ISC_LOG_TOFILEDESC, 87 ISC_LOG_DYNAMIC, 88 &destination, flags) == 89 ISC_R_SUCCESS); 90 RUNTIME_CHECK(isc_log_usechannel(lcfg, "_default", NULL, NULL) == 91 ISC_R_SUCCESS); 92 isc_log_setdebuglevel(lctx, level); 93 } 94 95 static void 96 print_addresses(dns_adbfind_t *find) { 97 dns_adbaddrinfo_t *address; 98 99 for (address = ISC_LIST_HEAD(find->list); 100 address != NULL; 101 address = ISC_LIST_NEXT(address, publink)) { 102 isc_netaddr_t netaddr; 103 char text[ISC_NETADDR_FORMATSIZE]; 104 isc_netaddr_fromsockaddr(&netaddr, &address->sockaddr); 105 isc_netaddr_format(&netaddr, text, sizeof(text)); 106 printf("%s\n", text); 107 } 108 } 109 110 static void 111 print_name(dns_name_t *name) { 112 char text[DNS_NAME_FORMATSIZE]; 113 114 dns_name_format(name, text, sizeof(text)); 115 printf("%s\n", text); 116 } 117 118 static void 119 do_find(isc_boolean_t want_event) { 120 isc_result_t result; 121 isc_boolean_t done = ISC_FALSE; 122 unsigned int options; 123 124 options = DNS_ADBFIND_INET | DNS_ADBFIND_INET6; 125 if (want_event) 126 options |= DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT; 127 dns_fixedname_init(&target); 128 result = dns_adb_createfind(view->adb, task, adb_callback, NULL, 129 dns_fixedname_name(&name), 130 dns_rootname, 0, options, 0, 131 dns_fixedname_name(&target), 0, 132 &find); 133 if (result == ISC_R_SUCCESS) { 134 if (!ISC_LIST_EMPTY(find->list)) { 135 /* 136 * We have at least some of the addresses for the 137 * name. 138 */ 139 INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0); 140 print_addresses(find); 141 done = ISC_TRUE; 142 } else { 143 /* 144 * We don't know any of the addresses for this 145 * name. 146 */ 147 if ((find->options & DNS_ADBFIND_WANTEVENT) == 0) { 148 /* 149 * And ADB isn't going to send us any events 150 * either. This query loses. 151 */ 152 done = ISC_TRUE; 153 } 154 /* 155 * If the DNS_ADBFIND_WANTEVENT flag was set, we'll 156 * get an event when something happens. 157 */ 158 } 159 } else if (result == DNS_R_ALIAS) { 160 print_name(dns_fixedname_name(&target)); 161 done = ISC_TRUE; 162 } else { 163 printf("dns_adb_createfind() returned %s\n", 164 isc_result_totext(result)); 165 done = ISC_TRUE; 166 } 167 168 if (done) { 169 if (find != NULL) 170 dns_adb_destroyfind(&find); 171 isc_app_shutdown(); 172 } 173 } 174 175 static void 176 adb_callback(isc_task_t *etask, isc_event_t *event) { 177 unsigned int type = event->ev_type; 178 179 REQUIRE(etask == task); 180 181 isc_event_free(&event); 182 dns_adb_destroyfind(&find); 183 184 if (type == DNS_EVENT_ADBMOREADDRESSES) 185 do_find(ISC_FALSE); 186 else if (type == DNS_EVENT_ADBNOMOREADDRESSES) { 187 printf("no more addresses\n"); 188 isc_app_shutdown(); 189 } else { 190 printf("unexpected ADB event type %u\n", type); 191 isc_app_shutdown(); 192 } 193 } 194 195 static void 196 run(isc_task_t *task, isc_event_t *event) { 197 UNUSED(task); 198 do_find(ISC_TRUE); 199 isc_event_free(&event); 200 } 201 202 int 203 main(int argc, char *argv[]) { 204 isc_boolean_t verbose = ISC_FALSE; 205 unsigned int workers = 2; 206 isc_timermgr_t *timermgr; 207 int ch; 208 isc_socketmgr_t *socketmgr; 209 dns_dispatchmgr_t *dispatchmgr; 210 dns_cache_t *cache; 211 isc_buffer_t b; 212 213 RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); 214 215 dns_result_register(); 216 217 mctx = NULL; 218 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 219 220 RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS); 221 RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE) 222 == ISC_R_SUCCESS); 223 224 while ((ch = isc_commandline_parse(argc, argv, "d:vw:")) != -1) { 225 switch (ch) { 226 case 'd': 227 level = (unsigned int)atoi(isc_commandline_argument); 228 break; 229 case 'v': 230 verbose = ISC_TRUE; 231 break; 232 case 'w': 233 workers = (unsigned int)atoi(isc_commandline_argument); 234 break; 235 } 236 } 237 238 log_init(); 239 240 if (verbose) { 241 printf("%u workers\n", workers); 242 printf("IPv4: %s\n", isc_result_totext(isc_net_probeipv4())); 243 printf("IPv6: %s\n", isc_result_totext(isc_net_probeipv6())); 244 } 245 246 taskmgr = NULL; 247 RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr) == 248 ISC_R_SUCCESS); 249 task = NULL; 250 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task) == 251 ISC_R_SUCCESS); 252 isc_task_setname(task, "byname", NULL); 253 254 dispatchmgr = NULL; 255 RUNTIME_CHECK(dns_dispatchmgr_create(mctx, NULL, &dispatchmgr) 256 == ISC_R_SUCCESS); 257 258 timermgr = NULL; 259 RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS); 260 socketmgr = NULL; 261 RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); 262 263 cache = NULL; 264 RUNTIME_CHECK(dns_cache_create(mctx, taskmgr, timermgr, 265 dns_rdataclass_in, "rbt", 0, NULL, 266 &cache) == ISC_R_SUCCESS); 267 268 view = NULL; 269 RUNTIME_CHECK(dns_view_create(mctx, dns_rdataclass_in, "default", 270 &view) == ISC_R_SUCCESS); 271 272 { 273 unsigned int attrs; 274 dns_dispatch_t *disp4 = NULL; 275 dns_dispatch_t *disp6 = NULL; 276 277 if (isc_net_probeipv4() == ISC_R_SUCCESS) { 278 isc_sockaddr_t any4; 279 isc_sockaddr_any(&any4); 280 281 attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; 282 RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, 283 socketmgr, 284 taskmgr, &any4, 285 512, 6, 1024, 286 17, 19, attrs, 287 attrs, &disp4) 288 == ISC_R_SUCCESS); 289 INSIST(disp4 != NULL); 290 } 291 292 if (isc_net_probeipv6() == ISC_R_SUCCESS) { 293 isc_sockaddr_t any6; 294 295 isc_sockaddr_any6(&any6); 296 297 attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP; 298 RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, 299 socketmgr, 300 taskmgr, &any6, 301 512, 6, 1024, 302 17, 19, attrs, 303 attrs, &disp6) 304 == ISC_R_SUCCESS); 305 INSIST(disp6 != NULL); 306 } 307 308 RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1, 309 socketmgr, 310 timermgr, 0, 311 dispatchmgr, 312 disp4, disp6) == 313 ISC_R_SUCCESS); 314 315 if (disp4 != NULL) 316 dns_dispatch_detach(&disp4); 317 if (disp6 != NULL) 318 dns_dispatch_detach(&disp6); 319 } 320 321 { 322 struct in_addr ina; 323 isc_sockaddr_t sa; 324 isc_sockaddrlist_t sal; 325 326 ISC_LIST_INIT(sal); 327 ina.s_addr = inet_addr("127.0.0.1"); 328 isc_sockaddr_fromin(&sa, &ina, 53); 329 ISC_LIST_APPEND(sal, &sa, link); 330 331 RUNTIME_CHECK(dns_fwdtable_add(view->fwdtable, dns_rootname, 332 &sal, dns_fwdpolicy_only) 333 == ISC_R_SUCCESS); 334 } 335 336 dns_view_setcache(view, cache); 337 dns_view_freeze(view); 338 339 dns_cache_detach(&cache); 340 341 printf("name = %s\n", argv[isc_commandline_index]); 342 isc_buffer_init(&b, argv[isc_commandline_index], 343 strlen(argv[isc_commandline_index])); 344 isc_buffer_add(&b, strlen(argv[isc_commandline_index])); 345 dns_fixedname_init(&name); 346 dns_fixedname_init(&target); 347 RUNTIME_CHECK(dns_name_fromtext(dns_fixedname_name(&name), &b, 348 dns_rootname, 0, NULL) == 349 ISC_R_SUCCESS); 350 351 RUNTIME_CHECK(isc_app_onrun(mctx, task, run, NULL) == ISC_R_SUCCESS); 352 353 (void)isc_app_run(); 354 355 dns_view_detach(&view); 356 isc_task_shutdown(task); 357 isc_task_detach(&task); 358 359 dns_dispatchmgr_destroy(&dispatchmgr); 360 361 isc_taskmgr_destroy(&taskmgr); 362 363 isc_socketmgr_destroy(&socketmgr); 364 isc_timermgr_destroy(&timermgr); 365 366 isc_log_destroy(&lctx); 367 368 isc_hash_destroy(); 369 isc_entropy_detach(&ectx); 370 371 if (verbose) 372 isc_mem_stats(mctx, stdout); 373 isc_mem_destroy(&mctx); 374 375 isc_app_finish(); 376 377 return (0); 378 } 379