main.c revision edcd1247ad7e81bb8b430e610d9718f64c70f05d
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews/*
a134177ed9f82189504191d90f3ed9e97c2b47cbTinderbox User * Copyright (C) 2000 Internet Software Consortium.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews *
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
00b872e4f76587584a2359e9001e9cf08b195ccfMark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * SOFTWARE.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <config.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <sys/types.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman#include <isc/app.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/assertions.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/event.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/mem.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/log.h>
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#include <isc/result.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/sockaddr.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/socket.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/task.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <isc/util.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <dns/resolver.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <dns/rootns.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <dns/log.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <lwres/lwres.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include <lwres/result.h>
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#include "client.h"
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews/*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * The goal number of clients we can handle will be NTASKS * NRECVS.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#define NTASKS 20 /* tasks to create to handle lwres queries */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#define NRECVS 5 /* max clients per task */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#define NTHREADS 1 /* # threads to create in thread manager */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews/*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * Array of client managers. Each of these will have a task associated
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * with it.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsclientmgr_t *cmgr;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsunsigned int ntasks; /* number of tasks actually created */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsdns_view_t *view;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsisc_taskmgr_t *taskmgr;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsisc_socketmgr_t *sockmgr;
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaramanisc_timermgr_t *timermgr;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsisc_sockaddrlist_t forwarders;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsstatic isc_result_t
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewscreate_view(isc_mem_t *mctx)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews{
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_cache_t *cache;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_result_t result;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_db_t *rootdb;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews view = NULL;
ad1317338af79edad878c9c3e4361798503310baMark Andrews cache = NULL;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews /*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * View.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews result = dns_view_create(mctx, dns_rdataclass_in, "_default", &view);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews if (result != ISC_R_SUCCESS)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews goto out;
ad1317338af79edad878c9c3e4361798503310baMark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews /*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * Cache.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews result = dns_cache_create(mctx, taskmgr, timermgr, dns_rdataclass_in,
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews "rbt", 0, NULL, &cache);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews if (result != ISC_R_SUCCESS)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews goto out;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_view_setcache(view, cache);
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt dns_cache_detach(&cache);
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt /*
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt * Resolver.
9a859983d7059a6eb9c877c1d2ac6a3a5b7170f7Evan Hunt *
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * XXXMLG hardwired number of tasks.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews result = dns_view_createresolver(view, taskmgr, 16, sockmgr,
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews timermgr, 0, NULL, NULL);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews if (result != ISC_R_SUCCESS)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews goto out;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews rootdb = NULL;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews result = dns_rootns_create(mctx, dns_rdataclass_in, NULL, &rootdb);
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman if (result != ISC_R_SUCCESS)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews goto out;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_view_sethints(view, rootdb);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_db_detach(&rootdb);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * If we have forwarders, set them here.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews if (ISC_LIST_HEAD(forwarders) != NULL) {
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_sockaddr_t *sa;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_resolver_setforwarders(view->resolver, &forwarders);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_resolver_setfwdpolicy(view->resolver, dns_fwdpolicy_only);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews sa = ISC_LIST_HEAD(forwarders);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews while (sa != NULL) {
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews ISC_LIST_UNLINK(forwarders, sa, link);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_mem_put(mctx, sa, sizeof (*sa));
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews sa = ISC_LIST_HEAD(forwarders);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews }
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews }
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_view_freeze(view);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews return (ISC_R_SUCCESS);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsout:
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews if (view != NULL)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_view_detach(&view);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews return (result);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews}
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews/*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * Wrappers around our memory management stuff, for the lwres functions.
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsstatic void *
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsmem_alloc(void *arg, size_t size)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews{
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews return (isc_mem_get(arg, size));
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews}
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsstatic void
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsmem_free(void *arg, void *mem, size_t size)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews{
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_mem_put(arg, mem, size);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews}
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaramanstatic void
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsparse_resolv_conf(isc_mem_t *mem)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews{
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwres_conf_t lwc;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwres_context_t *lwctx;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews int lwresult;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews struct in_addr ina;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews struct in6_addr ina6;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_sockaddr_t *sa;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews int i;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwctx = NULL;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwresult = lwres_context_create(&lwctx, mem, mem_alloc, mem_free);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews if (lwresult != LWRES_R_SUCCESS)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews return;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwres_conf_init(lwctx, &lwc);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwresult = lwres_conf_parse("/etc/resolv.conf", &lwc);
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman if (lwresult != LWRES_R_SUCCESS)
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews goto out;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#if 1
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwres_conf_print(stderr, &lwc);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews#endif
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews /*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * Run through the list of nameservers, and set them to be our
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * forwarders.
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews */
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews for (i = 0 ; i < lwc.nsnext ; i++) {
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews switch (lwc.nameservers[i].family) {
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews case AF_INET:
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews sa = isc_mem_get(mem, sizeof *sa);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews INSIST(sa != NULL);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews memcpy(&ina.s_addr, lwc.nameservers[i].address, 4);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_sockaddr_fromin(sa, &ina, 53);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews ISC_LIST_APPEND(forwarders, sa, link);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews sa = NULL;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews break;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews case AF_INET6:
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews sa = isc_mem_get(mem, sizeof *sa);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews INSIST(sa != NULL);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews memcpy(&ina6.s6_addr, lwc.nameservers[i].address, 16);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_sockaddr_fromin6(sa, &ina6, 53);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews ISC_LIST_APPEND(forwarders, sa, link);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews sa = NULL;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews break;
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman default:
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews break;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews }
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews }
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews out:
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwres_conf_clear(&lwc);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews lwres_context_destroy(&lwctx);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews}
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsint
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrewsmain(int argc, char **argv)
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman{
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_mem_t *mem;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_socket_t *sock;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_sockaddr_t localhost;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews struct in_addr lh_addr;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_result_t result;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews unsigned int i, j;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews client_t *client;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_logdestination_t destination;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_log_t *lctx;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews isc_logconfig_t *lcfg;
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews UNUSED(argc);
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman UNUSED(argv);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews dns_result_register();
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews result = isc_app_start();
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews INSIST(result == ISC_R_SUCCESS);
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews mem = NULL;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews result = isc_mem_create(0, 0, &mem);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews INSIST(result == ISC_R_SUCCESS);
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Set up logging.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews lctx = NULL;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews result = isc_log_create(mem, &lctx, &lcfg);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews INSIST(result == ISC_R_SUCCESS);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews dns_log_init(lctx);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews destination.file.stream = stderr;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews destination.file.name = NULL;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews destination.file.versions = ISC_LOG_ROLLNEVER;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews destination.file.maximum_size = 0;
b0ba1a6059b6d6c4b3aa77d8bc84cc443b981e01Mukund Sivaraman result = isc_log_createchannel(lcfg, "_default",
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ISC_LOG_TOFILEDESC,
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ISC_LOG_DYNAMIC,
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews &destination, ISC_LOG_PRINTTIME);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews INSIST(result == ISC_R_SUCCESS);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews INSIST(result == ISC_R_SUCCESS);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews * Set the initial debug level.
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews */
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews isc_log_setdebuglevel(lctx, 99);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews /*
89639a5e13cace9166bf14931b9e1ce9dc8c47a3Mark Andrews * Create a task manager.
*/
taskmgr = NULL;
result = isc_taskmgr_create(mem, NTHREADS, 0, &taskmgr);
INSIST(result == ISC_R_SUCCESS);
/*
* Create a socket manager.
*/
sockmgr = NULL;
result = isc_socketmgr_create(mem, &sockmgr);
INSIST(result == ISC_R_SUCCESS);
/*
* Create a timer manager.
*/
timermgr = NULL;
result = isc_timermgr_create(mem, &timermgr);
INSIST(result == ISC_R_SUCCESS);
/*
* Read resolv.conf to get our forwarders.
*/
ISC_LIST_INIT(forwarders);
parse_resolv_conf(mem);
/*
* Initialize the DNS bits. Start by loading our built-in
* root hints.
*/
result = create_view(mem);
INSIST(result == ISC_R_SUCCESS);
/*
* We'll need a socket. It will be a UDP socket, and bound to
* 127.0.0.1 port LWRES_UDP_PORT.
*/
sock = NULL;
result = isc_socket_create(sockmgr, AF_INET, isc_sockettype_udp,
&sock);
INSIST(result == ISC_R_SUCCESS);
lh_addr.s_addr = htonl(INADDR_LOOPBACK);
isc_sockaddr_fromin(&localhost, &lh_addr, LWRES_UDP_PORT);
result = isc_socket_bind(sock, &localhost);
INSIST(result == ISC_R_SUCCESS);
cmgr = isc_mem_get(mem, sizeof(clientmgr_t) * NTASKS);
INSIST(cmgr != NULL);
/*
* Create one task for each client manager.
*/
for (i = 0 ; i < NTASKS ; i++) {
cmgr[i].task = NULL;
cmgr[i].sock = sock;
cmgr[i].view = NULL;
cmgr[i].flags = 0;
ISC_EVENT_INIT(&cmgr[i].sdev, sizeof(isc_event_t),
ISC_EVENTATTR_NOPURGE,
0, LWRD_SHUTDOWN,
client_shutdown, &cmgr[i], (void *)main,
NULL, NULL);
ISC_LIST_INIT(cmgr[i].idle);
ISC_LIST_INIT(cmgr[i].running);
result = isc_task_create(taskmgr, mem, 0, &cmgr[i].task);
if (result != ISC_R_SUCCESS)
break;
isc_task_setname(cmgr[i].task, "lwresd client", &cmgr[i]);
cmgr[i].mctx = mem;
cmgr[i].lwctx = NULL;
result = lwres_context_create(&cmgr[i].lwctx, mem,
mem_alloc, mem_free);
if (result != ISC_R_SUCCESS) {
isc_task_detach(&cmgr[i].task);
break;
}
dns_view_attach(view, &cmgr[i].view);
}
INSIST(i > 0);
ntasks = i; /* remember how many we managed to create */
/*
* Now, run through each client manager and populate it with
* client structures. Do this by creating one receive for each
* task, in a loop, so each task has a chance of getting at least
* one client structure.
*/
for (i = 0 ; i < NRECVS ; i++) {
client = isc_mem_get(mem, sizeof(client_t) * ntasks);
if (client == NULL)
break;
for (j = 0 ; j < ntasks ; j++)
client_initialize(&client[j], &cmgr[j]);
}
INSIST(i > 0);
/*
* Issue one read request for each task we have.
*/
for (j = 0 ; j < ntasks ; j++) {
result = client_start_recv(&cmgr[j]);
INSIST(result == ISC_R_SUCCESS);
}
/*
* Wait for ^c or kill.
*/
isc_mem_stats(mem, stdout);
isc_app_run();
isc_mem_stats(mem, stdout);
/*
* Send a shutdown event to every task.
*/
for (j = 0 ; j < ntasks ; j++) {
isc_event_t *ev;
ev = &cmgr[j].sdev;
isc_task_send(cmgr[j].task, &ev);
printf("Sending shutdown events to task %p\n", cmgr[j].task);
}
/*
* Kill off the view.
*/
dns_view_detach(&view);
/*
* Wait for the tasks to all die.
*/
printf("Waiting for task manager to die...\n");
isc_taskmgr_destroy(&taskmgr);
/*
* Wait for everything to die off by waiting for the sockets
* to be detached.
*/
printf("Waiting for socket manager to die...\n");
isc_socket_detach(&sock);
isc_socketmgr_destroy(&sockmgr);
isc_timermgr_destroy(&timermgr);
/*
* Free up memory allocated. This is somewhat magical. We allocated
* the client_t's in blocks, but the first task always has the
* first pointer. Just loop here, freeing them.
*/
client = ISC_LIST_HEAD(cmgr[0].idle);
while (client != NULL) {
ISC_LIST_UNLINK(cmgr[0].idle, client, link);
isc_mem_put(mem, client, sizeof(client_t) * ntasks);
client = ISC_LIST_HEAD(cmgr[0].idle);
}
INSIST(ISC_LIST_EMPTY(cmgr[0].running));
/*
* Now, kill off the client manager structures.
*/
isc_mem_put(mem, cmgr, sizeof(clientmgr_t) * NTASKS);
cmgr = NULL;
isc_log_destroy(&lctx);
/*
* Kill the memory system.
*/
isc_mem_stats(mem, stdout);
isc_mem_destroy(&mem);
isc_app_finish();
return (0);
}