lwresd.c revision 45e1bd63587102c3bb361eaca42ee7b714fb3542
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Copyright (C) 2000-2003 Internet Software Consortium.
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Permission to use, copy, modify, and distribute this software for any
c869993e79c1eafbec61a56bf6cea848fe754c71xy * purpose with or without fee is hereby granted, provided that the above
c869993e79c1eafbec61a56bf6cea848fe754c71xy * copyright notice and this permission notice appear in all copies.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
c869993e79c1eafbec61a56bf6cea848fe754c71xy * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
c869993e79c1eafbec61a56bf6cea848fe754c71xy * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
c869993e79c1eafbec61a56bf6cea848fe754c71xy * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China * PERFORMANCE OF THIS SOFTWARE.
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/* $Id: lwresd.c,v 1.52 2006/02/28 02:39:51 marka Exp $ */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*! \file
c869993e79c1eafbec61a56bf6cea848fe754c71xy * \brief
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Main program for the Lightweight Resolver Daemon.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * To paraphrase the old saying about X11, "It's not a lightweight deamon
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China * for resolvers, it's a deamon for lightweight resolvers".
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <config.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <stdlib.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <string.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
fa25784ca4b51c206177d891a654f1d36a25d41fxy#include <isc/list.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/magic.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/mem.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/once.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/print.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/socket.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/task.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isc/util.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <isccfg/namedconf.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <dns/log.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <dns/result.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <dns/view.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <named/config.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <named/globals.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <named/log.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <named/lwaddr.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <named/lwresd.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <named/lwdclient.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <named/lwsearch.h>
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#include <named/server.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D')
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L')
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC)
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*!
c869993e79c1eafbec61a56bf6cea848fe754c71xy * The total number of clients we can handle will be NTASKS * NRECVS.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define NTASKS 2 /*%< tasks to create to handle lwres queries */
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define NRECVS 2 /*%< max clients per task */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xytypedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic ns_lwreslistenerlist_t listeners;
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_mutex_t listeners_lock;
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_once_t once = ISC_ONCE_INIT;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic void
c869993e79c1eafbec61a56bf6cea848fe754c71xyinitialize_mutex(void) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*%
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Wrappers around our memory management stuff, for the lwres functions.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid *
c869993e79c1eafbec61a56bf6cea848fe754c71xyns__lwresd_memalloc(void *arg, size_t size) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (isc_mem_get(arg, size));
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns__lwresd_memfree(void *arg, void *mem, size_t size) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_put(arg, mem, size);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define CHECK(op) \
c869993e79c1eafbec61a56bf6cea848fe754c71xy do { result = (op); \
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) goto cleanup; \
c869993e79c1eafbec61a56bf6cea848fe754c71xy } while (0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xybuffer_putstr(isc_buffer_t *b, const char *s) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy unsigned int len = strlen(s);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (isc_buffer_availablelength(b) <= len)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_NOSPACE);
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_buffer_putmem(b, (const unsigned char *)s, len);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Convert a resolv.conf file into a config structure.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyisc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx,
c869993e79c1eafbec61a56bf6cea848fe754c71xy cfg_obj_t **configp)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy char text[4096];
c869993e79c1eafbec61a56bf6cea848fe754c71xy char str[16];
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_buffer_t b;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_context_t *lwctx = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_conf_t *lwc = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_t sa;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_netaddr_t na;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int i;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_t result;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_result_t lwresult;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwctx = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns__lwresd_memfree,
c869993e79c1eafbec61a56bf6cea848fe754c71xy LWRES_CONTEXT_SERVERMODE);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresult != LWRES_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ISC_R_NOMEMORY;
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto cleanup;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresult != LWRES_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = DNS_R_SYNTAX;
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto cleanup;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwc = lwres_conf_get(lwctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(lwc != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_buffer_init(&b, text, sizeof(text));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "options {\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Build the list of forwarders.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwc->nsnext > 0) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\tforwarders {\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (i = 0; i < lwc->nsnext; i++) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(lwaddr_sockaddr_fromlwresaddr(
c869993e79c1eafbec61a56bf6cea848fe754c71xy &sa,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &lwc->nameservers[i],
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_g_port));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_netaddr_fromsockaddr(&na, &sa);
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(isc_netaddr_totext(&na, &b));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, ";\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Build the sortlist
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwc->sortlistnxt > 0) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\tsortlist {\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t{\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t\tany;\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t\t{\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (i = 0; i < lwc->sortlistnxt; i++) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_addr_t *lwaddr = &lwc->sortlist[i].addr;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_addr_t *lwmask = &lwc->sortlist[i].mask;
c869993e79c1eafbec61a56bf6cea848fe754c71xy unsigned int mask;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_netaddr_fromsockaddr(&na, &sa);
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = isc_netaddr_masktoprefixlen(&na, &mask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy char addrtext[ISC_NETADDR_FORMATSIZE];
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_netaddr_format(&na, addrtext,
c869993e79c1eafbec61a56bf6cea848fe754c71xy sizeof(addrtext));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LOG_ERROR,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "processing sortlist: '%s' is "
c869993e79c1eafbec61a56bf6cea848fe754c71xy "not a valid netmask",
c869993e79c1eafbec61a56bf6cea848fe754c71xy addrtext);
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto cleanup;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_netaddr_fromsockaddr(&na, &sa);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t\t\t"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(isc_netaddr_totext(&na, &b));
c869993e79c1eafbec61a56bf6cea848fe754c71xy snprintf(str, sizeof(str), "%u", mask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "/"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, str));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, ";\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t\t};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "};\n\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "lwres {\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Build the search path
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwc->searchnxt > 0) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwc->searchnxt > 0) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\tsearch {\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (i = 0; i < lwc->searchnxt; i++) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t\""));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, lwc->search[i]));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\";\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Build the ndots line
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwc->ndots != 1) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\tndots "));
c869993e79c1eafbec61a56bf6cea848fe754c71xy snprintf(str, sizeof(str), "%u", lwc->ndots);
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, str));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, ";\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Build the listen-on line
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwc->lwnext > 0) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\tlisten-on {\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (i = 0; i < lwc->lwnext; i++) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(lwaddr_sockaddr_fromlwresaddr(&sa,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &lwc->lwservers[i],
c869993e79c1eafbec61a56bf6cea848fe754c71xy 0));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_netaddr_fromsockaddr(&na, &sa);
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t\t"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(isc_netaddr_totext(&na, &b));
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, ";\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "\t};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
fa25784ca4b51c206177d891a654f1d36a25d41fxy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(buffer_putstr(&b, "};\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#if 0
c869993e79c1eafbec61a56bf6cea848fe754c71xy printf("%.*s\n",
c869993e79c1eafbec61a56bf6cea848fe754c71xy (int)isc_buffer_usedlength(&b),
c869993e79c1eafbec61a56bf6cea848fe754c71xy (char *)isc_buffer_base(&b));
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_conf_clear(lwctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_context_destroy(&lwctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy cleanup:
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwctx != NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_conf_clear(lwctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwres_context_destroy(&lwctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Handle lwresd manager objects
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyisc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwdmanager_create(isc_mem_t *mctx, const cfg_obj_t *lwres,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwresd_t **lwresdp)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwresd_t *lwresd;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const char *vname;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_rdataclass_t vclass;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_obj_t *obj, *viewobj, *searchobj;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_listelt_t *element;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_t result;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(lwresdp != NULL && *lwresdp == NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd == NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_NOMEMORY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->mctx = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_attach(mctx, &lwresd->mctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->view = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->search = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->refs = 1;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy obj = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy (void)cfg_map_get(lwres, "ndots", &obj);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (obj != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->ndots = cfg_obj_asuint32(obj);
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->ndots = 1;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->shutting_down = ISC_FALSE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy viewobj = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy (void)cfg_map_get(lwres, "view", &viewobj);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (viewobj != NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy obj = cfg_tuple_get(viewobj, "class");
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ns_config_getclass(obj, dns_rdataclass_in, &vclass);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS)
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto fail;
c869993e79c1eafbec61a56bf6cea848fe754c71xy } else {
c869993e79c1eafbec61a56bf6cea848fe754c71xy vname = "_default";
c869993e79c1eafbec61a56bf6cea848fe754c71xy vclass = dns_rdataclass_in;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &lwresd->view);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "couldn't find view %s", vname);
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto fail;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy searchobj = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy (void)cfg_map_get(lwres, "search", &searchobj);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (searchobj != NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->search = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ns_lwsearchlist_create(lwresd->mctx,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &lwresd->search);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "couldn't create searchlist");
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto fail;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (element = cfg_list_first(searchobj);
c869993e79c1eafbec61a56bf6cea848fe754c71xy element != NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy element = cfg_list_next(element))
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_obj_t *search;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const char *searchstr;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_buffer_t namebuf;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_fixedname_t fname;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_name_t *name;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy search = cfg_listelt_value(element);
fa25784ca4b51c206177d891a654f1d36a25d41fxy searchstr = cfg_obj_asstring(search);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_fixedname_init(&fname);
c869993e79c1eafbec61a56bf6cea848fe754c71xy name = dns_fixedname_name(&fname);
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_buffer_init(&namebuf, searchstr,
c869993e79c1eafbec61a56bf6cea848fe754c71xy strlen(searchstr));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_buffer_add(&namebuf, strlen(searchstr));
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = dns_name_fromtext(name, &namebuf,
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_rootname, ISC_FALSE,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "invalid name %s in searchlist",
c869993e79c1eafbec61a56bf6cea848fe754c71xy searchstr);
c869993e79c1eafbec61a56bf6cea848fe754c71xy continue;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ns_lwsearchlist_append(lwresd->search, name);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "couldn't update searchlist");
c869993e79c1eafbec61a56bf6cea848fe754c71xy goto fail;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->magic = LWRESD_MAGIC;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy *lwresdp = lwresd;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy fail:
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd->view != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_view_detach(&lwresd->view);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd->search != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwsearchlist_detach(&lwresd->search);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd->mctx != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_detach(&lwresd->mctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_put(mctx, lwresd, sizeof(ns_lwresd_t));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(VALID_LWRESD(source));
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(targetp != NULL && *targetp == NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&source->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy source->refs++;
c869993e79c1eafbec61a56bf6cea848fe754c71xy UNLOCK(&source->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy *targetp = source;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwdmanager_detach(ns_lwresd_t **lwresdp) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwresd_t *lwresd;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_t *mctx;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_boolean_t done = ISC_FALSE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(lwresdp != NULL && *lwresdp != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(VALID_LWRESD(*lwresdp));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd = *lwresdp;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *lwresdp = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&lwresd->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(lwresd->refs > 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->refs--;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd->refs == 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy done = ISC_TRUE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy UNLOCK(&lwresd->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!done)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy dns_view_detach(&lwresd->view);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd->search != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwsearchlist_detach(&lwresd->search);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mctx = lwresd->mctx;
c869993e79c1eafbec61a56bf6cea848fe754c71xy lwresd->magic = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_put(mctx, lwresd, sizeof(*lwresd));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_detach(&mctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Handle listener objects
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwreslistener_attach(ns_lwreslistener_t *source,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t **targetp)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(VALID_LWRESLISTENER(source));
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(targetp != NULL && *targetp == NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&source->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy source->refs++;
c869993e79c1eafbec61a56bf6cea848fe754c71xy UNLOCK(&source->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy *targetp = source;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwreslistener_detach(ns_lwreslistener_t **listenerp) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *listener;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_t *mctx;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_boolean_t done = ISC_FALSE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(listenerp != NULL && *listenerp != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(VALID_LWRESLISTENER(*listenerp));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener = *listenerp;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(listener->refs > 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->refs--;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (listener->refs == 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy done = ISC_TRUE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy UNLOCK(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!done)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (listener->manager != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwdmanager_detach(&listener->manager);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (listener->sock != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_socket_detach(&listener->sock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->magic = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mctx = listener->mctx;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_put(mctx, listener, sizeof(*listener));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_detach(&mctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy listenerp = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xylistener_create(isc_mem_t *mctx, ns_lwresd_t *lwresd,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t **listenerp)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *listener;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_t result;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy REQUIRE(listenerp != NULL && *listenerp == NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (listener == NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_NOMEMORY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = isc_mutex_init(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_put(mctx, listener, sizeof(ns_lwreslistener_t));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->magic = LWRESLISTENER_MAGIC;
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->refs = 1;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->sock = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->manager = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwdmanager_attach(lwresd, &listener->manager);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->mctx = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_attach(mctx, &listener->mctx);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LINK_INIT(listener, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_INIT(listener->cmgrs);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy *listenerp = listener;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xylistener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_socket_t *sock = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_t result = ISC_R_SUCCESS;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int pf;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy pf = isc_sockaddr_pf(address);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) ||
c869993e79c1eafbec61a56bf6cea848fe754c71xy (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS))
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_FAMILYNOSUPPORT);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->address = *address;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (isc_sockaddr_getport(&listener->address) == 0) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy in_port_t port;
c869993e79c1eafbec61a56bf6cea848fe754c71xy port = lwresd_g_listenport;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (port == 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy port = LWRES_UDP_PORT;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_setport(&listener->address, port);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy sock = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = isc_socket_create(ns_g_socketmgr, pf,
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockettype_udp, &sock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "failed to create lwres socket: %s",
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_totext(result));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = isc_socket_bind(sock, &listener->address);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy char socktext[ISC_SOCKADDR_FORMATSIZE];
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_format(&listener->address, socktext,
c869993e79c1eafbec61a56bf6cea848fe754c71xy sizeof(socktext));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_socket_detach(&sock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "failed to add lwres socket: %s: %s",
c869993e79c1eafbec61a56bf6cea848fe754c71xy socktext, isc_result_totext(result));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener->sock = sock;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic void
c869993e79c1eafbec61a56bf6cea848fe754c71xylistener_copysock(ns_lwreslistener_t *oldlistener,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *newlistener)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy newlistener->address = oldlistener->address;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_socket_attach(oldlistener->sock, &newlistener->sock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xylistener_startclients(ns_lwreslistener_t *listener) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwdclientmgr_t *cm;
c869993e79c1eafbec61a56bf6cea848fe754c71xy unsigned int i;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_t result;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Create the client managers.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ISC_R_SUCCESS;
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (i = 0; i < NTASKS && result == ISC_R_SUCCESS; i++)
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ns_lwdclientmgr_create(listener, NRECVS,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_g_taskmgr);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Ensure that we have created at least one.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (ISC_LIST_EMPTY(listener->cmgrs))
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Walk the list of clients and start each one up.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy cm = ISC_LIST_HEAD(listener->cmgrs);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (cm != NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = ns_lwdclient_startrecv(cm);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS)
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_ERROR,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "could not start lwres "
c869993e79c1eafbec61a56bf6cea848fe754c71xy "client handler: %s",
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_totext(result));
c869993e79c1eafbec61a56bf6cea848fe754c71xy cm = ISC_LIST_NEXT(cm, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy UNLOCK(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic void
c869993e79c1eafbec61a56bf6cea848fe754c71xylistener_shutdown(ns_lwreslistener_t *listener) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwdclientmgr_t *cm;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy cm = ISC_LIST_HEAD(listener->cmgrs);
c869993e79c1eafbec61a56bf6cea848fe754c71xy while (cm != NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_task_shutdown(cm->task);
c869993e79c1eafbec61a56bf6cea848fe754c71xy cm = ISC_LIST_NEXT(cm, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xyfind_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *listener;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy INSIST(listenerp != NULL && *listenerp == NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (listener = ISC_LIST_HEAD(listeners);
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener != NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener = ISC_LIST_NEXT(listener, link))
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!isc_sockaddr_equal(address, &listener->address))
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng continue;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *listenerp = listener;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_NOTFOUND);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy REQUIRE(VALID_LWRESLISTENER(listener));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_UNLINK(listener->cmgrs, cm, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy UNLOCK(&listener->lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing Chinans_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy REQUIRE(VALID_LWRESLISTENER(listener));
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * This does no locking, since it's called early enough that locking
c869993e79c1eafbec61a56bf6cea848fe754c71xy * isn't needed.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_APPEND(listener->cmgrs, cm, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic isc_result_t
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing Chinaconfigure_listener(isc_sockaddr_t *address, ns_lwresd_t *lwresd,
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_mem_t *mctx, ns_lwreslistenerlist_t *newlisteners)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *listener, *oldlistener = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy char socktext[ISC_SOCKADDR_FORMATSIZE];
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_t result;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy (void)find_listener(address, &oldlistener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = listener_create(mctx, lwresd, &listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_format(address, socktext, sizeof(socktext));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "lwres failed to configure %s: %s",
c869993e79c1eafbec61a56bf6cea848fe754c71xy socktext, isc_result_totext(result));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * If there's already a listener, don't rebind the socket.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (oldlistener == NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = listener_bind(listener, address);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_detach(&listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy } else
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng listener_copysock(oldlistener, listener);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = listener_startclients(listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_format(address, socktext, sizeof(socktext));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "lwres: failed to start %s: %s", socktext,
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_result_totext(result));
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_detach(&listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (oldlistener != NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Remove the old listener from the old list and shut it down.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_UNLINK(listeners, oldlistener, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener_shutdown(oldlistener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_detach(&oldlistener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy } else {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_format(address, socktext, sizeof(socktext));
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "lwres listening on %s", socktext);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_APPEND(*newlisteners, listener, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyisc_result_t
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwresd_configure(isc_mem_t *mctx, const cfg_obj_t *config) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_obj_t *lwreslist = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_obj_t *lwres = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_obj_t *listenerslist = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy const cfg_listelt_t *element = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *listener;
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China ns_lwreslistenerlist_t newlisteners;
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China isc_result_t result;
c869993e79c1eafbec61a56bf6cea848fe754c71xy char socktext[ISC_SOCKADDR_FORMATSIZE];
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_t *addrs = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwresd_t *lwresd = NULL;
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China isc_uint32_t count = 0;
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China
c869993e79c1eafbec61a56bf6cea848fe754c71xy REQUIRE(mctx != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy REQUIRE(config != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_INIT(newlisteners);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy result = cfg_map_get(config, "lwres", &lwreslist);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (result != ISC_R_SUCCESS)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy LOCK(&listeners_lock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Run through the new lwres address list, noting sockets that
c869993e79c1eafbec61a56bf6cea848fe754c71xy * are already being listened on and moving them to the new list.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Identifying duplicates addr/port combinations is left to either
c869993e79c1eafbec61a56bf6cea848fe754c71xy * the underlying config code, or to the bind attempt getting an
c869993e79c1eafbec61a56bf6cea848fe754c71xy * address-in-use error.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (element = cfg_list_first(lwreslist);
c869993e79c1eafbec61a56bf6cea848fe754c71xy element != NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy element = cfg_list_next(element))
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy in_port_t port;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China lwres = cfg_listelt_value(element);
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(ns_lwdmanager_create(mctx, lwres, &lwresd));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy port = lwresd_g_listenport;
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China if (port == 0)
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China port = LWRES_UDP_PORT;
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China
80a11ad227f9c82cd6e7cf5c8913a37f00b7af0echenlu chen - Sun Microsystems - Beijing China listenerslist = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy (void)cfg_map_get(lwres, "listen-on", &listenerslist);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (listenerslist == NULL) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy struct in_addr localhost;
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_t address;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy localhost.s_addr = htonl(INADDR_LOOPBACK);
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_fromin(&address, &localhost, port);
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(configure_listener(&address, lwresd, mctx,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &newlisteners));
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else {
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_uint32_t i;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(ns_config_getiplist(config, listenerslist,
c869993e79c1eafbec61a56bf6cea848fe754c71xy port, mctx, &addrs, &count));
c869993e79c1eafbec61a56bf6cea848fe754c71xy for (i = 0; i < count; i++)
c869993e79c1eafbec61a56bf6cea848fe754c71xy CHECK(configure_listener(&addrs[i], lwresd,
c869993e79c1eafbec61a56bf6cea848fe754c71xy mctx, &newlisteners));
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_config_putiplist(mctx, &addrs, count);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwdmanager_detach(&lwresd);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Shutdown everything on the listeners list, and remove them from
c869993e79c1eafbec61a56bf6cea848fe754c71xy * the list. Then put all of the new listeners on it.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy while (!ISC_LIST_EMPTY(listeners)) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener = ISC_LIST_HEAD(listeners);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_UNLINK(listeners, listener, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_sockaddr_format(&listener->address,
c869993e79c1eafbec61a56bf6cea848fe754c71xy socktext, sizeof(socktext));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener_shutdown(listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_detach(&listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL,
c869993e79c1eafbec61a56bf6cea848fe754c71xy NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE,
c869993e79c1eafbec61a56bf6cea848fe754c71xy "lwres no longer listening on %s", socktext);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy cleanup:
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_APPENDLIST(listeners, newlisteners, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (addrs != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_config_putiplist(mctx, &addrs, count);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (lwresd != NULL)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl ns_lwdmanager_detach(&lwresd);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl UNLOCK(&listeners_lock);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
c869993e79c1eafbec61a56bf6cea848fe754c71xy return (result);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid
c869993e79c1eafbec61a56bf6cea848fe754c71xyns_lwresd_shutdown(void) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_t *listener;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy while (!ISC_LIST_EMPTY(listeners)) {
c869993e79c1eafbec61a56bf6cea848fe754c71xy listener = ISC_LIST_HEAD(listeners);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ISC_LIST_UNLINK(listeners, listener, link);
c869993e79c1eafbec61a56bf6cea848fe754c71xy ns_lwreslistener_detach(&listener);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy