2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

Massive cleanup of error handling. Now errors in creating

the server object are always fatal, and errors that occur when
reconfiguring an existing server are always nonfatal.
This commit is contained in:
Andreas Gustafsson
2000-01-21 23:55:12 +00:00
parent b03de65d35
commit c0564c15e7
3 changed files with 173 additions and 248 deletions

View File

@@ -57,10 +57,12 @@ struct ns_server {
#define NS_SERVER_VALID(s) ((s) != NULL && \ #define NS_SERVER_VALID(s) ((s) != NULL && \
(s)->magic == NS_SERVER_MAGIC) (s)->magic == NS_SERVER_MAGIC)
isc_result_t void
ns_server_create(isc_mem_t *mctx, ns_server_t **serverp); ns_server_create(isc_mem_t *mctx, ns_server_t **serverp);
/* /*
* Create a server object with default settings. * Create a server object with default settings.
* This function either succeeds or causes the program to exit
* with a fatal error.
*/ */
void void

View File

@@ -239,10 +239,7 @@ setup() {
ns_main_earlyfatal("create_managers() failed: %s", ns_main_earlyfatal("create_managers() failed: %s",
isc_result_totext(result)); isc_result_totext(result));
result = ns_server_create(ns_g_mctx, &ns_g_server); ns_server_create(ns_g_mctx, &ns_g_server);
if (result != ISC_R_SUCCESS)
ns_main_earlyfatal("ns_server_create() failed: %s",
isc_result_totext(result));
} }
static void static void

View File

@@ -23,41 +23,35 @@
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <isc/app.h>
#include <isc/assertions.h> #include <isc/assertions.h>
#include <isc/dir.h>
#include <isc/error.h> #include <isc/error.h>
#include <isc/rwlock.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/result.h>
#include <isc/rwlock.h>
#include <isc/socket.h>
#include <isc/task.h> #include <isc/task.h>
#include <isc/thread.h> #include <isc/thread.h>
#include <isc/result.h>
#include <isc/socket.h>
#include <isc/timer.h> #include <isc/timer.h>
#include <isc/app.h>
#include <isc/dir.h>
#include <isc/util.h> #include <isc/util.h>
#include <dns/aclconf.h> #include <dns/aclconf.h>
#include <dns/cache.h> #include <dns/cache.h>
#include <dns/confparser.h> #include <dns/confparser.h>
#include <dns/types.h> #include <dns/db.h>
#include <dns/result.h> #include <dns/fixedname.h>
#include <dns/journal.h>
#include <dns/master.h> #include <dns/master.h>
#include <dns/name.h> #include <dns/name.h>
#include <dns/fixedname.h>
#include <dns/rdata.h> #include <dns/rdata.h>
#include <dns/rdatalist.h> #include <dns/result.h>
#include <dns/rdataset.h> #include <dns/tkey.h>
#include <dns/rdatasetiter.h> #include <dns/tsig.h>
#include <dns/compress.h> #include <dns/types.h>
#include <dns/db.h>
#include <dns/dbtable.h>
#include <dns/message.h>
#include <dns/journal.h>
#include <dns/view.h> #include <dns/view.h>
#include <dns/zone.h> #include <dns/zone.h>
#include <dns/zoneconf.h> #include <dns/zoneconf.h>
#include <dns/tsig.h>
#include <dns/tkey.h>
#include <named/client.h> #include <named/client.h>
#include <named/globals.h> #include <named/globals.h>
@@ -68,12 +62,42 @@
#include <named/server.h> #include <named/server.h>
#include <named/types.h> #include <named/types.h>
/*
* Check an operation for failure. Assumes that the function
* using it has a 'result' variable and a 'cleanup' label.
*/
#define CHECK(op) \
do { result = (op); \
if (result != ISC_R_SUCCESS) goto cleanup; \
} while (0)
#define CHECKM(op, msg) \
do { result = (op); \
if (result != ISC_R_SUCCESS) { \
isc_log_write(ns_g_lctx, \
NS_LOGCATEGORY_GENERAL, \
NS_LOGMODULE_SERVER, \
ISC_LOG_ERROR, \
"%s: %s", msg, \
isc_result_totext(result)); \
goto cleanup; \
} \
} while (0) \
#define CHECKFATAL(op, msg) \
do { result = (op); \
if (result != ISC_R_SUCCESS) \
fatal(msg, result); \
} while (0) \
typedef struct { typedef struct {
isc_mem_t * mctx; isc_mem_t * mctx;
dns_viewlist_t viewlist; dns_viewlist_t viewlist;
dns_aclconfctx_t *aclconf; dns_aclconfctx_t *aclconf;
} ns_load_t; } ns_load_t;
static void fatal(char *msg, isc_result_t result);
/* /*
* Configure 'view' according to 'cctx'. * Configure 'view' according to 'cctx'.
* *
@@ -93,10 +117,8 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx)
* Cache. * Cache.
*/ */
cache = NULL; cache = NULL;
result = dns_cache_create(mctx, ns_g_taskmgr, ns_g_timermgr, CHECK(dns_cache_create(mctx, ns_g_taskmgr, ns_g_timermgr,
view->rdclass, "rbt", 0, NULL, &cache); view->rdclass, "rbt", 0, NULL, &cache));
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_view_setcache(view, cache); dns_view_setcache(view, cache);
cleaning_interval = 3600; /* Default is 1 hour. */ cleaning_interval = 3600; /* Default is 1 hour. */
(void) dns_c_ctx_getcleaninterval(cctx, &cleaning_interval); (void) dns_c_ctx_getcleaninterval(cctx, &cleaning_interval);
@@ -111,9 +133,7 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx)
NS_LOGMODULE_SERVER, NS_LOGMODULE_SERVER,
ISC_LOG_DEBUG(1), "loading cache '%s'", ISC_LOG_DEBUG(1), "loading cache '%s'",
ns_g_cachefile); ns_g_cachefile);
result = dns_db_load(view->cachedb, ns_g_cachefile); CHECK(dns_db_load(view->cachedb, ns_g_cachefile));
if (result != ISC_R_SUCCESS)
goto cleanup;
} }
/* /*
@@ -122,11 +142,9 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx)
* XXXRTH hardwired number of tasks. Also, we'll need to * XXXRTH hardwired number of tasks. Also, we'll need to
* see if we are dealing with a shared dispatcher in this view. * see if we are dealing with a shared dispatcher in this view.
*/ */
result = dns_view_createresolver(view, ns_g_taskmgr, 31, CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
ns_g_socketmgr, ns_g_timermgr, ns_g_socketmgr, ns_g_timermgr,
NULL); NULL));
if (result != ISC_R_SUCCESS)
goto cleanup;
/* /*
* We have default hints for class IN. * We have default hints for class IN.
@@ -135,16 +153,12 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx)
dns_view_sethints(view, ns_g_server->roothints); dns_view_sethints(view, ns_g_server->roothints);
/* /*
* Load the TSIG keys * Configure the view's TSIG keys.
*/ */
ring = NULL; ring = NULL;
result = dns_tsig_init(cctx, view->mctx, &ring); CHECK(dns_tsig_init(cctx, view->mctx, &ring));
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_view_setkeyring(view, ring); dns_view_setkeyring(view, ring);
return (ISC_R_SUCCESS);
cleanup: cleanup:
return (result); return (result);
} }
@@ -194,43 +208,27 @@ create_version_view(dns_c_ctx_t *configctx, dns_view_t **viewp) {
r.length = 1 + len; r.length = 1 + len;
dns_rdata_fromregion(&rdata, dns_rdataclass_ch, dns_rdatatype_txt, &r); dns_rdata_fromregion(&rdata, dns_rdataclass_ch, dns_rdatatype_txt, &r);
result = dns_zone_create(&zone, ns_g_mctx); CHECK(dns_zone_create(&zone, ns_g_mctx));
if (result != ISC_R_SUCCESS) CHECK(dns_zone_setorigin(zone, &origin));
goto cleanup;
result = dns_zone_setorigin(zone, &origin);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_db_create(ns_g_mctx, "rbt", &origin, ISC_FALSE, CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, ISC_FALSE,
dns_rdataclass_ch, 0, NULL, &db); dns_rdataclass_ch, 0, NULL, &db));
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_db_newversion(db, &dbver); CHECK(dns_db_newversion(db, &dbver));
if (result != DNS_R_SUCCESS)
goto cleanup;
dns_difftuple_create(ns_g_mctx, DNS_DIFFOP_ADD, &origin, CHECK(dns_difftuple_create(ns_g_mctx, DNS_DIFFOP_ADD, &origin,
0, &rdata, &tuple); 0, &rdata, &tuple));
dns_diff_append(&diff, &tuple); dns_diff_append(&diff, &tuple);
result = dns_diff_apply(&diff, db, dbver); CHECK(dns_diff_apply(&diff, db, dbver));
if (result != DNS_R_SUCCESS)
goto cleanup;
dns_db_closeversion(db, &dbver, ISC_TRUE); dns_db_closeversion(db, &dbver, ISC_TRUE);
result = dns_view_create(ns_g_mctx, dns_rdataclass_ch, "_version", CHECK(dns_view_create(ns_g_mctx, dns_rdataclass_ch, "_version",
&view); &view));
if (result != ISC_R_SUCCESS)
return (result);
result = dns_zone_replacedb(zone, db, ISC_FALSE); CHECK(dns_zone_replacedb(zone, db, ISC_FALSE));
if (result != DNS_R_SUCCESS)
goto cleanup;
result = dns_view_addzone(view, zone); CHECK(dns_view_addzone(view, zone));
if (result != DNS_R_SUCCESS)
goto cleanup;
dns_view_freeze(view); dns_view_freeze(view);
@@ -281,16 +279,12 @@ load_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
*/ */
corigin = NULL; corigin = NULL;
/* XXX casting away const */ /* XXX casting away const */
result = dns_c_zone_getname(czone, (const char **) &corigin); CHECK(dns_c_zone_getname(czone, (const char **) &corigin));
if (result != DNS_R_SUCCESS)
goto cleanup;
isc_buffer_init(&buffer, corigin, strlen(corigin), ISC_BUFFERTYPE_TEXT); isc_buffer_init(&buffer, corigin, strlen(corigin), ISC_BUFFERTYPE_TEXT);
isc_buffer_add(&buffer, strlen(corigin)); isc_buffer_add(&buffer, strlen(corigin));
dns_fixedname_init(&fixorigin); dns_fixedname_init(&fixorigin);
result = dns_name_fromtext(dns_fixedname_name(&fixorigin), CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
&buffer, dns_rootname, ISC_FALSE, NULL); &buffer, dns_rootname, ISC_FALSE, NULL));
if (result != DNS_R_SUCCESS)
goto cleanup;
origin = dns_fixedname_name(&fixorigin); origin = dns_fixedname_name(&fixorigin);
/* /*
@@ -307,10 +301,8 @@ load_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
goto cleanup; goto cleanup;
if (view == NULL) { if (view == NULL) {
dns_view_t *tview = NULL; dns_view_t *tview = NULL;
result = dns_view_create(ns_g_mctx, czone->zclass, CHECK(dns_view_create(ns_g_mctx, czone->zclass,
viewname, &view); viewname, &view));
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_view_attach(view, &tview); dns_view_attach(view, &tview);
ISC_LIST_APPEND(lctx->viewlist, tview, link); ISC_LIST_APPEND(lctx->viewlist, tview, link);
} }
@@ -357,25 +349,16 @@ load_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
* create a new one. * create a new one.
*/ */
if (zone == NULL) { if (zone == NULL) {
result = dns_zone_create(&zone, lctx->mctx); CHECK(dns_zone_create(&zone, lctx->mctx));
if (result != ISC_R_SUCCESS) CHECK(dns_zone_setorigin(zone, origin));
goto cleanup; CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr,
result = dns_zone_setorigin(zone, origin); zone));
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_zonemgr_managezone(ns_g_server->zonemgr,
zone);
if (result != ISC_R_SUCCESS)
goto cleanup;
/* XXX Unmanage? */
} }
/* /*
* Configure the zone. * Configure the zone.
*/ */
result = dns_zone_configure(cctx, lctx->aclconf, czone, zone); CHECK(dns_zone_configure(cctx, lctx->aclconf, czone, zone));
if (result != ISC_R_SUCCESS)
goto cleanup;
/* /*
* XXX Why was this here? * XXX Why was this here?
@@ -387,9 +370,7 @@ load_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
/* /*
* Add the zone to its view in the new view list. * Add the zone to its view in the new view list.
*/ */
result = dns_view_addzone(view, zone); CHECK(dns_view_addzone(view, zone));
if (result != ISC_R_SUCCESS)
goto cleanup;
cleanup: cleanup:
if (tzone != NULL) if (tzone != NULL)
@@ -404,26 +385,30 @@ load_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
return (result); return (result);
} }
/* XXX will need error recovery for reconfig */ /*
static void * Configure a single server ACL at '*aclp'. Get its configuration by
* calling 'getacl'.
*/
static isc_result_t
configure_server_acl(dns_c_ctx_t *cctx, dns_aclconfctx_t *actx, isc_mem_t *mctx, configure_server_acl(dns_c_ctx_t *cctx, dns_aclconfctx_t *actx, isc_mem_t *mctx,
isc_result_t (*getcacl)(dns_c_ctx_t *, dns_c_ipmatchlist_t **), isc_result_t (*getcacl)(dns_c_ctx_t *, dns_c_ipmatchlist_t **),
dns_acl_t **aclp) dns_acl_t **aclp)
{ {
isc_result_t result; isc_result_t result = ISC_R_SUCCESS;
dns_c_ipmatchlist_t *cacl = NULL; dns_c_ipmatchlist_t *cacl = NULL;
if (*aclp != NULL) if (*aclp != NULL)
dns_acl_detach(aclp); dns_acl_detach(aclp);
(void) (*getcacl)(cctx, &cacl); (void) (*getcacl)(cctx, &cacl);
if (cacl != NULL) { if (cacl != NULL) {
result = dns_acl_fromconfig(cacl, cctx, actx, mctx, aclp); result = dns_acl_fromconfig(cacl, cctx, actx, mctx, aclp);
if (result != DNS_R_SUCCESS)
ns_server_fatal(NS_LOGMODULE_SERVER, ISC_FALSE,
"server ACL setup failed");
dns_c_ipmatchlist_detach(&cacl); dns_c_ipmatchlist_detach(&cacl);
} }
return (result);
} }
/*
* Configure a single server quota.
*/
static void static void
configure_server_quota(dns_c_ctx_t *cctx, configure_server_quota(dns_c_ctx_t *cctx,
isc_result_t (*getquota)(dns_c_ctx_t *, isc_int32_t *), isc_result_t (*getquota)(dns_c_ctx_t *, isc_int32_t *),
@@ -434,14 +419,14 @@ configure_server_quota(dns_c_ctx_t *cctx,
quota->max = val; quota->max = val;
} }
static void static isc_result_t
load_configuration(const char *filename, ns_server_t *server) { load_configuration(const char *filename, ns_server_t *server) {
isc_result_t result; isc_result_t result;
ns_load_t lctx; ns_load_t lctx;
dns_c_cbks_t callbacks; dns_c_cbks_t callbacks;
dns_c_ctx_t *configctx; dns_c_ctx_t *configctx;
dns_view_t *view, *view_next; dns_view_t *view, *view_next;
dns_viewlist_t oviewlist; dns_viewlist_t tmpviewlist;
dns_aclconfctx_t aclconfctx; dns_aclconfctx_t aclconfctx;
dns_aclconfctx_init(&aclconfctx); dns_aclconfctx_init(&aclconfctx);
@@ -465,21 +450,8 @@ load_configuration(const char *filename, ns_server_t *server) {
* load_zone() through 'callbacks'. * load_zone() through 'callbacks'.
*/ */
configctx = NULL; configctx = NULL;
result = dns_c_parse_namedconf(filename, ns_g_mctx, &configctx, CHECK(dns_c_parse_namedconf(filename, ns_g_mctx, &configctx,
&callbacks); &callbacks));
if (result != ISC_R_SUCCESS) {
#ifdef notyet
for (view = ISC_LIST_HEAD(lctx.viewlist);
view != NULL;
view = view_next) {
view_next = ISC_LIST_NEXT(view, link);
ISC_LIST_UNLINK(lctx.viewlist, view, link);
dns_view_detach(&view);
}
#endif
ns_server_fatal(NS_LOGMODULE_SERVER, ISC_FALSE,
"load of '%s' failed", filename);
}
/* /*
* Configure various server options. * Configure various server options.
@@ -488,14 +460,16 @@ load_configuration(const char *filename, ns_server_t *server) {
(void) dns_c_ctx_getauthnxdomain(configctx, &server->auth_nxdomain); (void) dns_c_ctx_getauthnxdomain(configctx, &server->auth_nxdomain);
(void) dns_c_ctx_gettransferformat(configctx, &server->transfer_format); (void) dns_c_ctx_gettransferformat(configctx, &server->transfer_format);
configure_server_acl(configctx, &aclconfctx, ns_g_mctx, CHECK(configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
dns_c_ctx_getqueryacl, &server->queryacl); dns_c_ctx_getqueryacl, &server->queryacl));
configure_server_acl(configctx, &aclconfctx, ns_g_mctx, CHECK(configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
dns_c_ctx_getrecursionacl, &server->recursionacl); dns_c_ctx_getrecursionacl,
&server->recursionacl));
configure_server_acl(configctx, &aclconfctx, ns_g_mctx, CHECK(configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
dns_c_ctx_gettransferacl, &server->transferacl); dns_c_ctx_gettransferacl,
&server->transferacl));
configure_server_quota(configctx, dns_c_ctx_gettransfersout, configure_server_quota(configctx, dns_c_ctx_gettransfersout,
&server->xfroutquota, 10); &server->xfroutquota, 10);
@@ -520,10 +494,9 @@ load_configuration(const char *filename, ns_server_t *server) {
ns_g_mctx, &listenon); ns_g_mctx, &listenon);
} else { } else {
/* Not specified, use default. */ /* Not specified, use default. */
result = ns_listenlist_default(ns_g_mctx, ns_g_port, CHECK(ns_listenlist_default(ns_g_mctx, ns_g_port,
&listenon); &listenon));
} }
RUNTIME_CHECK(result == ISC_R_SUCCESS);
ns_interfacemgr_setlistenon(server->interfacemgr, listenon); ns_interfacemgr_setlistenon(server->interfacemgr, listenon);
ns_listenlist_detach(&listenon); ns_listenlist_detach(&listenon);
} }
@@ -534,13 +507,9 @@ load_configuration(const char *filename, ns_server_t *server) {
*/ */
if (ISC_LIST_EMPTY(lctx.viewlist)) { if (ISC_LIST_EMPTY(lctx.viewlist)) {
view = NULL; view = NULL;
result = dns_view_create(ns_g_mctx, dns_rdataclass_in, CHECKM(dns_view_create(ns_g_mctx, dns_rdataclass_in,
"_default", &view); "_default", &view),
if (result != ISC_R_SUCCESS) { "creating default view");
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not create default view");
goto cleanup;
}
ISC_LIST_APPEND(lctx.viewlist, view, link); ISC_LIST_APPEND(lctx.viewlist, view, link);
} }
@@ -553,9 +522,7 @@ load_configuration(const char *filename, ns_server_t *server) {
view != NULL; view != NULL;
view = ISC_LIST_NEXT(view, link)) view = ISC_LIST_NEXT(view, link))
{ {
result = configure_view(view, configctx, ns_g_mctx); CHECK(configure_view(view, configctx, ns_g_mctx));
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_view_freeze(view); dns_view_freeze(view);
} }
@@ -563,12 +530,7 @@ load_configuration(const char *filename, ns_server_t *server) {
* Create (or recreate) the version view. * Create (or recreate) the version view.
*/ */
view = NULL; view = NULL;
result = create_version_view(configctx, &view); CHECK(create_version_view(configctx, &view));
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not create version view");
goto cleanup;
}
ISC_LIST_APPEND(lctx.viewlist, view, link); ISC_LIST_APPEND(lctx.viewlist, view, link);
view = NULL; view = NULL;
@@ -578,11 +540,15 @@ load_configuration(const char *filename, ns_server_t *server) {
if (configctx->options != NULL && if (configctx->options != NULL &&
configctx->options->directory != NULL) { configctx->options->directory != NULL) {
result = isc_dir_chdir(configctx->options->directory); result = isc_dir_chdir(configctx->options->directory);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS) {
ns_server_fatal(NS_LOGMODULE_SERVER, ISC_FALSE, isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
"change directory to '%s' failed: %s", NS_LOGMODULE_SERVER,
ISC_LOG_ERROR, "change directory "
"to '%s' failed: %s",
configctx->options->directory, configctx->options->directory,
isc_result_totext(result)); isc_result_totext(result));
CHECK(result);
}
} }
/* /*
@@ -592,6 +558,7 @@ load_configuration(const char *filename, ns_server_t *server) {
view != NULL; view != NULL;
view = view_next) { view = view_next) {
view_next = ISC_LIST_NEXT(view, link); view_next = ISC_LIST_NEXT(view, link);
/* XXX error checking */
dns_view_load(view); dns_view_load(view);
} }
@@ -600,44 +567,24 @@ load_configuration(const char *filename, ns_server_t *server) {
* so that we know when we need to force AXFR of * so that we know when we need to force AXFR of
* slave zones whose master files are missing. * slave zones whose master files are missing.
*/ */
dns_zonemgr_forcemaint(server->zonemgr); CHECK(dns_zonemgr_forcemaint(server->zonemgr));
/* /*
* Put the configuration into production. * Swap our new view list with the production one.
*/ */
RWLOCK(&server->viewlock, isc_rwlocktype_write); RWLOCK(&server->viewlock, isc_rwlocktype_write);
tmpviewlist = server->viewlist;
oviewlist = server->viewlist;
server->viewlist = lctx.viewlist; server->viewlist = lctx.viewlist;
lctx.viewlist = tmpviewlist;
RWUNLOCK(&server->viewlock, isc_rwlocktype_write); RWUNLOCK(&server->viewlock, isc_rwlocktype_write);
/*
* Cleanup old configuration.
*/
for (view = ISC_LIST_HEAD(oviewlist);
view != NULL;
view = view_next) {
view_next = ISC_LIST_NEXT(view, link);
ISC_LIST_UNLINK(oviewlist, view, link);
dns_view_detach(&view);
}
if (ns_g_tkeyctx != NULL)
dns_tkey_destroy(&ns_g_tkeyctx);
/* /*
* Load the TKEY information from the configuration * Load the TKEY information from the configuration
*/ */
result = dns_tkey_init(configctx, ns_g_mctx, &ns_g_tkeyctx); if (ns_g_tkeyctx != NULL)
if (result != ISC_R_SUCCESS) { dns_tkey_destroy(&ns_g_tkeyctx);
ns_server_fatal(NS_LOGMODULE_SERVER, ISC_FALSE, CHECKM(dns_tkey_init(configctx, ns_g_mctx, &ns_g_tkeyctx),
"dns_tkey_init() failed: %s", "setting up TKEY");
isc_result_totext(result));
}
/* /*
* Rescan the interface list to pick up changes in the * Rescan the interface list to pick up changes in the
* listen-on option. * listen-on option.
@@ -647,8 +594,21 @@ load_configuration(const char *filename, ns_server_t *server) {
dns_aclconfctx_destroy(&aclconfctx); dns_aclconfctx_destroy(&aclconfctx);
dns_c_ctx_delete(&configctx); dns_c_ctx_delete(&configctx);
cleanup: cleanup:
; /* XXX */ /*
* This cleans up either the old production view list
* or our temporary list depending on whether they
* were swapped above or not.
*/
for (view = ISC_LIST_HEAD(lctx.viewlist);
view != NULL;
view = view_next) {
view_next = ISC_LIST_NEXT(view, link);
ISC_LIST_UNLINK(lctx.viewlist, view, link);
dns_view_detach(&view);
}
return (result);
} }
static void static void
@@ -659,28 +619,17 @@ run_server(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event); isc_event_free(&event);
result = ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, CHECKFATAL(ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
&server->clientmgr); &server->clientmgr),
if (result != ISC_R_SUCCESS) { "creating client manager");
UNEXPECTED_ERROR(__FILE__, __LINE__,
"ns_clientmgr_create() failed: %s",
isc_result_totext(result));
/* XXX cleanup */
return;
}
result = ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr,
ns_g_socketmgr, server->clientmgr, ns_g_socketmgr, server->clientmgr,
&server->interfacemgr); &server->interfacemgr),
if (result != ISC_R_SUCCESS) { "creating interface manager");
UNEXPECTED_ERROR(__FILE__, __LINE__,
"ns_interfacemgr_create() failed: %s",
isc_result_totext(result));
/* XXX cleanup */
return;
}
load_configuration(ns_g_conffile, server); CHECKFATAL(load_configuration(ns_g_conffile, server),
"loading configuration");
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "running"); ISC_LOG_INFO, "running");
@@ -720,13 +669,14 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event); isc_event_free(&event);
} }
isc_result_t void
ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
isc_result_t result; isc_result_t result;
ns_server_t *server = isc_mem_get(mctx, sizeof(*server)); ns_server_t *server = isc_mem_get(mctx, sizeof(*server));
if (server == NULL) if (server == NULL)
return (ISC_R_NOMEMORY); fatal("allocating server object", ISC_R_NOMEMORY);
server->mctx = mctx; server->mctx = mctx;
server->task = NULL; server->task = NULL;
@@ -755,42 +705,26 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
server->roothints = NULL; server->roothints = NULL;
result = ns_rootns_create(mctx, &server->roothints); CHECKFATAL(ns_rootns_create(mctx, &server->roothints),
RUNTIME_CHECK(result == ISC_R_SUCCESS); "setting up root hints");
/* /*
* Setup the server task, which is responsible for coordinating * Setup the server task, which is responsible for coordinating
* startup and shutdown of the server. * startup and shutdown of the server.
*/ */
result = isc_task_create(ns_g_taskmgr, ns_g_mctx, 0, &server->task); CHECKFATAL(isc_task_create(ns_g_taskmgr, ns_g_mctx, 0, &server->task),
if (result != ISC_R_SUCCESS) "creating server task");
goto cleanup; CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server),
result = isc_task_onshutdown(server->task, shutdown_server, server); "isc_task_onshutdown");
if (result != ISC_R_SUCCESS) CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server),
goto cleanup_task; "isc_app_onrun");
result = isc_app_onrun(ns_g_mctx, server->task, run_server, server);
if (result != ISC_R_SUCCESS)
goto cleanup_task;
result = dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
ns_g_socketmgr, &server->zonemgr); ns_g_socketmgr, &server->zonemgr),
if (result != ISC_R_SUCCESS) { "dns_zonemgr_create");
UNEXPECTED_ERROR(__FILE__, __LINE__,
"ns_zonemgr_create() failed: %s",
isc_result_totext(result));
/* XXX cleanup */
return (result);
}
server->magic = NS_SERVER_MAGIC; server->magic = NS_SERVER_MAGIC;
*serverp = server; *serverp = server;
return (ISC_R_SUCCESS);
cleanup_task:
isc_task_detach(&server->task);
cleanup:
/* XXX more cleanup */
return (result);
} }
void void
@@ -822,20 +756,12 @@ ns_server_destroy(ns_server_t **serverp) {
isc_mem_put(server->mctx, server, sizeof(*server)); isc_mem_put(server->mctx, server, sizeof(*server));
} }
void static void
ns_server_fatal(isc_logmodule_t *module, isc_boolean_t want_core, fatal(char *msg, isc_result_t result)
const char *format, ...)
{ {
va_list args; isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_CRITICAL, "%s: %s", msg, isc_result_totext(result));
va_start(args, format);
isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, module,
ISC_LOG_CRITICAL, format, args);
va_end(args);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_CRITICAL, "exiting (due to fatal error)"); ISC_LOG_CRITICAL, "exiting (due to fatal error)");
if (want_core && ns_g_coreok)
abort();
exit(1); exit(1);
} }