lwresd.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Copyright (C) 2000-2009, 2012-2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* $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>
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;
}
}
}
else
} else if (ns_g_lwresdonly)
else
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;
"listener_startclients: creating %d "
"managers with %d clients each",
/*
* Create the client managers.
*/
if (result != ISC_R_SUCCESS)
break;
}
/*
* If the list is empty return now with the previous
* ns_lwdclientmgr_create() result.
*/
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)) {
}
}