lwresd.c revision 313b0ea9f258edd8530f4454c69e6ba194280162
/*
* Copyright (C) 2004-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwresd.c,v 1.60 2009/09/02 23:48:01 tbox Exp $ */
/*! \file
* \brief
* Main program for the Lightweight Resolver Daemon.
*
* To paraphrase the old saying about X11, "It's not a lightweight deamon
* for resolvers, it's a deamon for lightweight resolvers".
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <isccfg/namedconf.h>
#include <named/lwdclient.h>
#include <named/lwsearch.h>
/*!
* The total number of clients we can handle will be NTASKS * NRECVS.
*/
static ns_lwreslistenerlist_t listeners;
static isc_mutex_t listeners_lock;
static void
initialize_mutex(void) {
}
/*%
* Wrappers around our memory management stuff, for the lwres functions.
*/
void *
}
void
}
} while (0)
static isc_result_t
buffer_putstr(isc_buffer_t *b, const char *s) {
if (isc_buffer_availablelength(b) <= len)
return (ISC_R_NOSPACE);
isc_buffer_putmem(b, (const unsigned char *)s, len);
return (ISC_R_SUCCESS);
}
/*
* Convert a resolv.conf file into a config structure.
*/
{
char text[4096];
char str[16];
isc_buffer_t b;
int i;
if (lwresult != LWRES_R_SUCCESS) {
goto cleanup;
}
if (lwresult != LWRES_R_SUCCESS) {
goto cleanup;
}
/*
* Build the list of forwarders.
*/
&sa,
&lwc->nameservers[i],
ns_g_port));
}
}
/*
* Build the sortlist
*/
if (lwc->sortlistnxt > 0) {
for (i = 0; i < lwc->sortlistnxt; i++) {
unsigned int mask;
if (result != ISC_R_SUCCESS) {
char addrtext[ISC_NETADDR_FORMATSIZE];
sizeof(addrtext));
"processing sortlist: '%s' is "
"not a valid netmask",
addrtext);
goto cleanup;
}
}
}
/*
* Build the search path
*/
}
}
}
/*
* Build the ndots line
*/
}
/*
* Build the listen-on line
*/
0));
}
}
#if 0
printf("%.*s\n",
(int)isc_buffer_usedlength(&b),
(char *)isc_buffer_base(&b));
#endif
}
return (result);
}
/*
* Handle lwresd manager objects
*/
{
const char *vname;
const cfg_listelt_t *element;
return (ISC_R_NOMEMORY);
else
if (result != ISC_R_SUCCESS)
goto fail;
} else {
vname = "_default";
}
if (result != ISC_R_SUCCESS) {
"couldn't find view %s", vname);
goto fail;
}
if (result != ISC_R_SUCCESS) {
"couldn't create searchlist");
goto fail;
}
{
const char *searchstr;
dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
"invalid name %s in searchlist",
continue;
}
if (result != ISC_R_SUCCESS) {
"couldn't update searchlist");
goto fail;
}
}
}
return (ISC_R_SUCCESS);
fail:
return (result);
}
void
}
void
if (!done)
return;
}
/*
* Handle listener objects
*/
void
{
}
void
if (!done)
return;
}
static isc_result_t
{
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
int pf;
return (ISC_R_FAMILYNOSUPPORT);
if (port == 0)
}
if (result != ISC_R_SUCCESS) {
"failed to create lwres socket: %s",
return (result);
}
if (result != ISC_R_SUCCESS) {
char socktext[ISC_SOCKADDR_FORMATSIZE];
sizeof(socktext));
"failed to add lwres socket: %s: %s",
return (result);
}
return (ISC_R_SUCCESS);
}
static void
{
}
static isc_result_t
unsigned int i;
/*
* Create the client managers.
*/
/*
* Ensure that we have created at least one.
*/
return (result);
/*
* Walk the list of clients and start each one up.
*/
if (result != ISC_R_SUCCESS)
"could not start lwres "
"client handler: %s",
}
return (ISC_R_SUCCESS);
}
static void
}
}
static isc_result_t
{
continue;
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
}
void
{
}
void
/*
* This does no locking, since it's called early enough that locking
* isn't needed.
*/
}
static isc_result_t
{
char socktext[ISC_SOCKADDR_FORMATSIZE];
if (result != ISC_R_SUCCESS) {
"lwres failed to configure %s: %s",
return (result);
}
/*
* If there's already a listener, don't rebind the socket.
*/
if (oldlistener == NULL) {
if (result != ISC_R_SUCCESS) {
return (ISC_R_SUCCESS);
}
} else
if (result != ISC_R_SUCCESS) {
"lwres: failed to start %s: %s", socktext,
return (ISC_R_SUCCESS);
}
if (oldlistener != NULL) {
/*
* Remove the old listener from the old list and shut it down.
*/
} else {
"lwres listening on %s", socktext);
}
return (result);
}
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_uint32_t count = 0;
if (result != ISC_R_SUCCESS)
return (ISC_R_SUCCESS);
/*
* Run through the new lwres address list, noting sockets that
* are already being listened on and moving them to the new list.
*
* the underlying config code, or to the bind attempt getting an
* address-in-use error.
*/
{
if (port == 0)
if (listenerslist == NULL) {
&newlisteners));
} else {
isc_uint32_t i;
&count));
for (i = 0; i < count; i++)
mctx, &newlisteners));
}
}
/*
* Shutdown everything on the listeners list, and remove them from
* the list. Then put all of the new listeners on it.
*/
while (!ISC_LIST_EMPTY(listeners)) {
"lwres no longer listening on %s", socktext);
}
return (result);
}
void
ns_lwresd_shutdown(void) {
while (!ISC_LIST_EMPTY(listeners)) {
}
}