mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-15 00:10:04 -04:00
Throttled answer while loading support (still needs config file hooks).
This commit is contained in:
parent
1162a4e02a
commit
d22b4de3f1
9 changed files with 736 additions and 60 deletions
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.h,v 1.35 2000/08/01 01:12:16 tale Exp $ */
|
||||
/* $Id: server.h,v 1.36 2000/09/05 03:35:16 marka Exp $ */
|
||||
|
||||
#ifndef NAMED_SERVER_H
|
||||
#define NAMED_SERVER_H 1
|
||||
|
|
@ -53,6 +53,7 @@ struct ns_server {
|
|||
dns_aclenv_t aclenv;
|
||||
|
||||
/* Server data structures. */
|
||||
dns_loadmgr_t * loadmgr;
|
||||
dns_zonemgr_t * zonemgr;
|
||||
ns_clientmgr_t * clientmgr;
|
||||
dns_viewlist_t viewlist;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.c,v 1.217 2000/08/31 12:15:07 marka Exp $ */
|
||||
/* $Id: server.c,v 1.218 2000/09/05 03:35:14 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include <dns/forward.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/keytable.h>
|
||||
#include <dns/master.h>
|
||||
#include <dns/peer.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/resolver.h>
|
||||
|
|
@ -429,6 +430,11 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
|
|||
port = 53;
|
||||
dns_view_setdstport(view, port);
|
||||
|
||||
/*
|
||||
* Attach load manager to view.
|
||||
*/
|
||||
dns_view_setloadmgr(view, ns_g_server->loadmgr);
|
||||
|
||||
/*
|
||||
* Configure the view's cache. Try to reuse an existing
|
||||
* cache if possible, otherwise create a new cache.
|
||||
|
|
@ -1315,6 +1321,8 @@ load_configuration(const char *filename, ns_server_t *server,
|
|||
configure_server_quota(cctx, dns_c_ctx_getrecursiveclients,
|
||||
&server->recursionquota, 1000);
|
||||
|
||||
/* dns_loadmgr_setlimit(server->loadmgr, 20); XXXMPA */
|
||||
|
||||
/*
|
||||
* Configure the zone manager.
|
||||
*/
|
||||
|
|
@ -1725,6 +1733,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
|
|||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
/* Initialize server data structures. */
|
||||
server->loadmgr = NULL;
|
||||
server->zonemgr = NULL;
|
||||
server->clientmgr = NULL;
|
||||
server->interfacemgr = NULL;
|
||||
|
|
@ -1774,6 +1783,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
|
|||
CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
|
||||
ns_g_socketmgr, &server->zonemgr),
|
||||
"dns_zonemgr_create");
|
||||
CHECKFATAL(dns_loadmgr_create(ns_g_mctx, &server->loadmgr),
|
||||
"dns_loadmgr_create");
|
||||
|
||||
server->magic = NS_SERVER_MAGIC;
|
||||
*serverp = server;
|
||||
|
|
@ -1784,6 +1795,7 @@ ns_server_destroy(ns_server_t **serverp) {
|
|||
ns_server_t *server = *serverp;
|
||||
REQUIRE(NS_SERVER_VALID(server));
|
||||
|
||||
dns_loadmgr_detach(&server->loadmgr);
|
||||
dns_zonemgr_detach(&server->zonemgr);
|
||||
|
||||
if (server->tkeyctx != NULL)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: events.h,v 1.30 2000/08/31 12:15:14 marka Exp $ */
|
||||
/* $Id: events.h,v 1.31 2000/09/05 03:35:21 marka Exp $ */
|
||||
|
||||
#ifndef DNS_EVENTS_H
|
||||
#define DNS_EVENTS_H 1
|
||||
|
|
@ -54,6 +54,7 @@
|
|||
#define DNS_EVENT_ZONESTARTXFRIN (ISC_EVENTCLASS_DNS + 25)
|
||||
#define DNS_EVENT_MASTERQUANTUM (ISC_EVENTCLASS_DNS + 26)
|
||||
#define DNS_EVENT_CACHEOVERMEM (ISC_EVENTCLASS_DNS + 27)
|
||||
#define DNS_EVENT_MASTERNEXTZONE (ISC_EVENTCLASS_DNS + 28)
|
||||
|
||||
#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
|
||||
#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.h,v 1.23 2000/08/15 03:33:51 marka Exp $ */
|
||||
/* $Id: master.h,v 1.24 2000/09/05 03:35:22 marka Exp $ */
|
||||
|
||||
#ifndef DNS_MASTER_H
|
||||
#define DNS_MASTER_H 1
|
||||
|
|
@ -96,6 +96,15 @@ dns_master_loadbufferinc(isc_buffer_t *buffer,
|
|||
dns_loaddonefunc_t done, void *done_arg,
|
||||
isc_mem_t *mctx);
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfilequota(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
isc_boolean_t age_ttl, dns_rdatacallbacks_t *callbacks,
|
||||
isc_task_t *task, dns_loaddonefunc_t done,
|
||||
void *done_arg, dns_loadmgr_t *lmgr,
|
||||
dns_loadctx_t **ctxp, isc_mem_t *mctx);
|
||||
|
||||
|
||||
/*
|
||||
* Loads a RFC 1305 master file from a file, stream, or buffer into rdatasets
|
||||
* and then calls 'callbacks->commit' to commit the rdatasets. Rdata memory
|
||||
|
|
@ -122,6 +131,8 @@ dns_master_loadbufferinc(isc_buffer_t *buffer,
|
|||
* 'callbacks->done' points to a valid function or NULL.
|
||||
* 'mctx' points to a valid memory context.
|
||||
* 'task' and 'done' to be NULL or 'task' and 'done' to be valid.
|
||||
* 'lmgr' to be valid.
|
||||
* 'ctxp != NULL && ctxp == NULL'.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS upon successfully loading the master file.
|
||||
|
|
@ -137,6 +148,103 @@ dns_master_loadbufferinc(isc_buffer_t *buffer,
|
|||
* Any error code from callbacks->commit().
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadctx_detach(dns_loadctx_t **ctxp);
|
||||
/*
|
||||
* Detach from the load context.
|
||||
*
|
||||
* Requires:
|
||||
* '*ctxp' to be valid.
|
||||
*
|
||||
* Ensures:
|
||||
* '*ctxp == NULL'
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target);
|
||||
/*
|
||||
* Attach to the load context.
|
||||
*
|
||||
* Requires:
|
||||
* 'source' to be valid.
|
||||
* 'target != NULL && *target == NULL'.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadctx_cancel(dns_loadctx_t *ctx);
|
||||
/*
|
||||
* Cancel loading the zone file associated with this load context.
|
||||
*
|
||||
* Requires:
|
||||
* 'ctx' to be valid
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_loadmgr_create(isc_mem_t *mctx, dns_loadmgr_t **mgrp);
|
||||
/*
|
||||
* Create a new load manager.
|
||||
*
|
||||
* Requires:
|
||||
* 'mgrp != NULL && *mgrp == NULL'
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS upon successfully creating a load manager.
|
||||
* ISC_R_MEMORY
|
||||
* ISC_R_UNEXPECTED
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadmgr_cancel(dns_loadmgr_t *mgr);
|
||||
/*
|
||||
* Cancel all queue loads. Loads that are already in progress are not
|
||||
* canceled.
|
||||
*
|
||||
* Requires:
|
||||
* 'mgr' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadmgr_attach(dns_loadmgr_t *source, dns_loadmgr_t **target);
|
||||
/*
|
||||
* Attach to the load manager.
|
||||
*
|
||||
* Requires:
|
||||
* 'source' to be valid.
|
||||
* 'target != NULL && *target == NULL'
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadmgr_detach(dns_loadmgr_t **mgrp);
|
||||
/*
|
||||
* Detach from the load manager.
|
||||
*
|
||||
* Requires:
|
||||
* '*mgrp' to be valid.
|
||||
*
|
||||
* Ensures:
|
||||
* '*mgr == NULL'
|
||||
*/
|
||||
|
||||
void
|
||||
dns_loadmgr_setlimit(dns_loadmgr_t *mgr, isc_uint32_t limit);
|
||||
/*
|
||||
* Set the number of simultaneous loads permitted by the load manager.
|
||||
* 0 is unlimited.
|
||||
*
|
||||
* Requires:
|
||||
* 'mgr' to be valid.
|
||||
*/
|
||||
|
||||
isc_uint32_t
|
||||
dns_loadmgr_getlimit(dns_loadmgr_t *mgr);
|
||||
/*
|
||||
* Return the number of simultaneous loads permitted by the load manager.
|
||||
* 0 is unlimited.
|
||||
*
|
||||
* Requires:
|
||||
* 'mgr' to be valid.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_MASTER_H */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: types.h,v 1.93 2000/08/24 22:15:37 bwelling Exp $ */
|
||||
/* $Id: types.h,v 1.94 2000/09/05 03:35:23 marka Exp $ */
|
||||
|
||||
#ifndef DNS_TYPES_H
|
||||
#define DNS_TYPES_H 1
|
||||
|
|
@ -64,6 +64,8 @@ typedef isc_uint16_t dns_keyflags_t;
|
|||
typedef struct dns_keynode dns_keynode_t;
|
||||
typedef struct dns_keytable dns_keytable_t;
|
||||
typedef isc_uint16_t dns_keytag_t;
|
||||
typedef struct dns_loadctx dns_loadctx_t;
|
||||
typedef struct dns_loadmgr dns_loadmgr_t;
|
||||
typedef struct dns_message dns_message_t;
|
||||
typedef isc_uint16_t dns_messageid_t;
|
||||
typedef isc_region_t dns_label_t;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.h,v 1.51 2000/08/25 01:16:04 bwelling Exp $ */
|
||||
/* $Id: view.h,v 1.52 2000/09/05 03:35:24 marka Exp $ */
|
||||
|
||||
#ifndef DNS_VIEW_H
|
||||
#define DNS_VIEW_H 1
|
||||
|
|
@ -80,6 +80,7 @@ struct dns_view {
|
|||
dns_zt_t * zonetable;
|
||||
dns_resolver_t * resolver;
|
||||
dns_adb_t * adb;
|
||||
dns_loadmgr_t * loadmgr;
|
||||
dns_requestmgr_t * requestmgr;
|
||||
dns_cache_t * cache;
|
||||
dns_db_t * cachedb;
|
||||
|
|
@ -600,6 +601,9 @@ dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg);
|
|||
* see dns_tsig_verify()
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_setloadmgr(dns_view_t *view, dns_loadmgr_t *loadmgr);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_VIEW_H */
|
||||
|
|
|
|||
459
lib/dns/master.c
459
lib/dns/master.c
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.c,v 1.63 2000/08/24 19:13:13 gson Exp $ */
|
||||
/* $Id: master.c,v 1.64 2000/09/05 03:35:17 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -82,13 +82,12 @@ typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t;
|
|||
/*
|
||||
* Master file loading state that persists across $INCLUDEs.
|
||||
*/
|
||||
typedef struct loadctx loadctx_t;
|
||||
|
||||
struct loadctx {
|
||||
struct dns_loadctx {
|
||||
isc_uint32_t magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_lex_t *lex;
|
||||
loadctx_t *parent;
|
||||
dns_loadctx_t *parent;
|
||||
dns_rdatacallbacks_t *callbacks;
|
||||
isc_task_t *task;
|
||||
dns_loaddonefunc_t done;
|
||||
|
|
@ -113,13 +112,38 @@ struct loadctx {
|
|||
int origin_in_use;
|
||||
unsigned int loop_cnt; /* records per quantum,
|
||||
* 0 => all. */
|
||||
isc_boolean_t canceled;
|
||||
/* Rate limit goo. */
|
||||
isc_boolean_t rate_limited;
|
||||
ISC_LINK(dns_loadctx_t) link;
|
||||
char *master_file;
|
||||
dns_loadmgr_t *loadmgr;
|
||||
isc_event_t event;
|
||||
|
||||
isc_mutex_t lock;
|
||||
/* locked by lock */
|
||||
isc_uint32_t references;
|
||||
};
|
||||
|
||||
#define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x')
|
||||
#define DNS_LCTX_VALID(ctx) ISC_MAGIC_VALID(ctx, DNS_LCTX_MAGIC)
|
||||
|
||||
struct dns_loadmgr {
|
||||
isc_uint32_t magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_uint32_t erefs;
|
||||
isc_uint32_t irefs;
|
||||
isc_mutex_t lock;
|
||||
isc_uint32_t active;
|
||||
isc_uint32_t limit;
|
||||
ISC_LIST(dns_loadctx_t) list;
|
||||
};
|
||||
|
||||
#define DNS_LMGR_MAGIC ISC_MAGIC('L','m','g','r')
|
||||
#define DNS_LMGR_VALID(ctx) ISC_MAGIC_VALID(ctx, DNS_LMGR_MAGIC)
|
||||
|
||||
static isc_result_t
|
||||
pushfile(const char *master_file, dns_name_t *origin, loadctx_t **ctxp);
|
||||
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t **ctxp);
|
||||
|
||||
static isc_result_t
|
||||
commit(dns_rdatacallbacks_t *, isc_lex_t *, rdatalist_head_t *, dns_name_t *,
|
||||
|
|
@ -143,7 +167,25 @@ static void
|
|||
load_quantum(isc_task_t *task, isc_event_t *event);
|
||||
|
||||
static isc_result_t
|
||||
task_send(loadctx_t *ctx);
|
||||
task_send(dns_loadctx_t *ctx);
|
||||
|
||||
static void
|
||||
loadctx_destroy(dns_loadctx_t *ctx);
|
||||
|
||||
static void
|
||||
loadmgr_start(isc_task_t *task, isc_event_t *event);
|
||||
|
||||
static void
|
||||
loadmgr_cancel(dns_loadmgr_t *mgr);
|
||||
|
||||
static void
|
||||
loadmgr_iattach(dns_loadmgr_t *source, dns_loadmgr_t **target);
|
||||
|
||||
static void
|
||||
loadmgr_idetach(dns_loadmgr_t **mgrp);
|
||||
|
||||
static void
|
||||
loadmgr_destroy(dns_loadmgr_t *mgr);
|
||||
|
||||
#define GETTOKEN(lexer, options, token, eol) \
|
||||
do { \
|
||||
|
|
@ -224,20 +266,52 @@ gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token,
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
loadctx_destroy(loadctx_t **ctxp) {
|
||||
loadctx_t *ctx;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
void
|
||||
dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
|
||||
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
REQUIRE(DNS_LCTX_VALID(source));
|
||||
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0); /* Overflow? */
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_loadctx_detach(dns_loadctx_t **ctxp) {
|
||||
dns_loadctx_t *ctx;
|
||||
isc_boolean_t need_destroy = ISC_FALSE;
|
||||
|
||||
REQUIRE(ctxp != NULL);
|
||||
ctx = *ctxp;
|
||||
REQUIRE(DNS_LCTX_VALID(ctx));
|
||||
|
||||
LOCK(&ctx->lock);
|
||||
INSIST(ctx->references > 0);
|
||||
ctx->references--;
|
||||
if (ctx->references == 0)
|
||||
need_destroy = ISC_TRUE;
|
||||
UNLOCK(&ctx->lock);
|
||||
|
||||
if (need_destroy)
|
||||
loadctx_destroy(ctx);
|
||||
*ctxp = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
loadctx_destroy(dns_loadctx_t *ctx) {
|
||||
isc_mem_t *mctx;
|
||||
|
||||
REQUIRE(DNS_LCTX_VALID(ctx));
|
||||
|
||||
ctx->magic = 0;
|
||||
if (ctx->parent != NULL)
|
||||
loadctx_destroy(&ctx->parent);
|
||||
dns_loadctx_detach(&ctx->parent);
|
||||
|
||||
if (ctx->lex != NULL) {
|
||||
isc_lex_close(ctx->lex);
|
||||
|
|
@ -245,6 +319,13 @@ loadctx_destroy(loadctx_t **ctxp) {
|
|||
}
|
||||
if (ctx->task != NULL)
|
||||
isc_task_detach(&ctx->task);
|
||||
if (ctx->master_file != NULL) {
|
||||
isc_mem_free(ctx->mctx, ctx->master_file);
|
||||
ctx->master_file = NULL;
|
||||
}
|
||||
if (ctx->loadmgr != NULL)
|
||||
loadmgr_idetach(&ctx->loadmgr);
|
||||
DESTROYLOCK(&ctx->lock);
|
||||
mctx = NULL;
|
||||
isc_mem_attach(ctx->mctx, &mctx);
|
||||
isc_mem_detach(&ctx->mctx);
|
||||
|
|
@ -257,9 +338,9 @@ loadctx_create(isc_mem_t *mctx, isc_boolean_t age_ttl, dns_name_t *top,
|
|||
dns_rdataclass_t zclass, dns_name_t *origin,
|
||||
dns_rdatacallbacks_t *callbacks, isc_task_t *task,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
loadctx_t **ctxp)
|
||||
dns_loadctx_t **ctxp)
|
||||
{
|
||||
loadctx_t *ctx;
|
||||
dns_loadctx_t *ctx;
|
||||
isc_result_t result;
|
||||
isc_region_t r;
|
||||
int i;
|
||||
|
|
@ -279,6 +360,14 @@ loadctx_create(isc_mem_t *mctx, isc_boolean_t age_ttl, dns_name_t *top,
|
|||
ctx = isc_mem_get(mctx, sizeof(*ctx));
|
||||
if (ctx == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
result = isc_mutex_init(&ctx->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, ctx, sizeof *ctx);
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_mutex_init() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
|
||||
ctx->lex = NULL;
|
||||
result = isc_lex_create(mctx, TOKENSIZ, &ctx->lex);
|
||||
|
|
@ -328,8 +417,18 @@ loadctx_create(isc_mem_t *mctx, isc_boolean_t age_ttl, dns_name_t *top,
|
|||
ctx->done = done;
|
||||
ctx->done_arg = done_arg;
|
||||
|
||||
ctx->rate_limited = ISC_FALSE;
|
||||
ctx->master_file = NULL;
|
||||
ctx->loadmgr = NULL;
|
||||
ISC_LINK_INIT(ctx, link);
|
||||
ISC_EVENT_INIT(&ctx->event, sizeof(ctx->event), 0, NULL,
|
||||
DNS_EVENT_MASTERNEXTZONE, loadmgr_start,
|
||||
ctx, ctx, NULL, NULL);
|
||||
|
||||
ctx->canceled = ISC_FALSE;
|
||||
ctx->mctx = NULL;
|
||||
isc_mem_attach(mctx, &ctx->mctx);
|
||||
ctx->references = 1; /* Implicit attach. */
|
||||
ctx->magic = DNS_LCTX_MAGIC;
|
||||
*ctxp = ctx;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
|
@ -340,7 +439,7 @@ loadctx_create(isc_mem_t *mctx, isc_boolean_t age_ttl, dns_name_t *top,
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
load(loadctx_t **ctxp) {
|
||||
load(dns_loadctx_t **ctxp) {
|
||||
dns_rdataclass_t rdclass;
|
||||
dns_rdatatype_t type, covers;
|
||||
isc_uint32_t ttl_offset = 0;
|
||||
|
|
@ -376,7 +475,7 @@ load(loadctx_t **ctxp) {
|
|||
unsigned int loop_cnt = 0;
|
||||
isc_mem_t *mctx;
|
||||
dns_rdatacallbacks_t *callbacks;
|
||||
loadctx_t *ctx;
|
||||
dns_loadctx_t *ctx;
|
||||
|
||||
|
||||
ctx = *ctxp;
|
||||
|
|
@ -416,7 +515,7 @@ load(loadctx_t **ctxp) {
|
|||
CTX_COPYVAR(ctx, *ctxp, ttl);
|
||||
CTX_COPYVAR(ctx, *ctxp, default_ttl);
|
||||
CTX_COPYVAR(ctx, *ctxp, warn_1035);
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
ctx = *ctxp;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -993,10 +1092,10 @@ load(loadctx_t **ctxp) {
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
pushfile(const char *master_file, dns_name_t *origin, loadctx_t **ctxp) {
|
||||
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t **ctxp) {
|
||||
isc_result_t result;
|
||||
loadctx_t *ctx;
|
||||
loadctx_t *new = NULL;
|
||||
dns_loadctx_t *ctx;
|
||||
dns_loadctx_t *new = NULL;
|
||||
isc_region_t r;
|
||||
int new_in_use;
|
||||
|
||||
|
|
@ -1043,7 +1142,7 @@ pushfile(const char *master_file, dns_name_t *origin, loadctx_t **ctxp) {
|
|||
|
||||
cleanup:
|
||||
if (new != NULL)
|
||||
loadctx_destroy(&new);
|
||||
dns_loadctx_detach(&new);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1053,7 +1152,7 @@ dns_master_loadfile(const char *master_file, dns_name_t *top,
|
|||
dns_rdataclass_t zclass, isc_boolean_t age_ttl,
|
||||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
||||
{
|
||||
loadctx_t *ctx = NULL;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
||||
|
|
@ -1070,10 +1169,110 @@ dns_master_loadfile(const char *master_file, dns_name_t *top,
|
|||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfilequota(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
isc_boolean_t age_ttl, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done,
|
||||
void *done_arg, dns_loadmgr_t *lmgr,
|
||||
dns_loadctx_t **ctxp, isc_mem_t *mctx)
|
||||
{
|
||||
isc_boolean_t queue;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
isc_result_t result;
|
||||
isc_event_t *event;
|
||||
|
||||
REQUIRE(DNS_LMGR_VALID(lmgr));
|
||||
REQUIRE(ctxp != NULL && *ctxp == NULL);
|
||||
|
||||
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
||||
callbacks, task, done, done_arg, &ctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
ctx->rate_limited = ISC_TRUE;
|
||||
ctx->master_file = isc_mem_strdup(mctx, master_file);
|
||||
if (ctx->master_file == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
loadmgr_iattach(lmgr, &ctx->loadmgr);
|
||||
|
||||
LOCK(&lmgr->lock);
|
||||
lmgr->active++;
|
||||
queue = ISC_TF((lmgr->limit != 0 && lmgr->active > lmgr->limit));
|
||||
if (queue)
|
||||
ISC_LIST_APPEND(lmgr->list, ctx, link);
|
||||
INSIST(queue || ISC_LIST_EMPTY(lmgr->list));
|
||||
UNLOCK(&lmgr->lock);
|
||||
|
||||
dns_loadctx_attach(ctx, ctxp);
|
||||
result = DNS_R_CONTINUE;
|
||||
if (!queue) {
|
||||
event = &ctx->event;
|
||||
isc_task_send(ctx->task, &event);
|
||||
}
|
||||
return (result);
|
||||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
loadmgr_done(dns_loadctx_t *ctx, isc_result_t result) {
|
||||
dns_loadctx_t *next;
|
||||
isc_event_t *event;
|
||||
|
||||
if (ctx->done != NULL)
|
||||
(ctx->done)(ctx->done_arg, result);
|
||||
|
||||
LOCK(&ctx->loadmgr->lock);
|
||||
INSIST(ctx->loadmgr->active > 0);
|
||||
ctx->loadmgr->active--;
|
||||
/* dequeue */
|
||||
next = ISC_LIST_HEAD(ctx->loadmgr->list);
|
||||
if (next != NULL)
|
||||
ISC_LIST_UNLINK(ctx->loadmgr->list, next, link);
|
||||
UNLOCK(&ctx->loadmgr->lock);
|
||||
if (next != NULL) {
|
||||
event = &next->event;
|
||||
isc_task_send(next->task, &event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
loadmgr_start(isc_task_t *task, isc_event_t *event) {
|
||||
dns_loadctx_t *ctx = event->ev_arg;
|
||||
isc_result_t result;
|
||||
|
||||
INSIST(task == ctx->task);
|
||||
|
||||
if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto done;
|
||||
}
|
||||
result = isc_lex_openfile(ctx->lex, ctx->master_file);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = load(&ctx);
|
||||
if (result == DNS_R_CONTINUE) {
|
||||
result = task_send(ctx);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
isc_event_free(&event);
|
||||
return;
|
||||
}
|
||||
done:
|
||||
loadmgr_done(ctx, result);
|
||||
isc_event_free(&event);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
|
|
@ -1081,7 +1280,7 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
|||
isc_task_t *task, dns_loaddonefunc_t done,
|
||||
void *done_arg, isc_mem_t *mctx)
|
||||
{
|
||||
loadctx_t *ctx = NULL;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
isc_result_t tresult;
|
||||
isc_result_t result;
|
||||
|
||||
|
|
@ -1106,7 +1305,7 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
|||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1116,7 +1315,7 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
|||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
||||
{
|
||||
isc_result_t result;
|
||||
loadctx_t *ctx = NULL;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
|
||||
REQUIRE(stream != NULL);
|
||||
|
||||
|
|
@ -1134,7 +1333,7 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
|||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1147,7 +1346,7 @@ dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
|||
{
|
||||
isc_result_t result;
|
||||
isc_result_t tresult;
|
||||
loadctx_t *ctx = NULL;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
|
||||
REQUIRE(stream != NULL);
|
||||
|
||||
|
|
@ -1172,7 +1371,7 @@ dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
|||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1183,7 +1382,7 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top,
|
|||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
||||
{
|
||||
isc_result_t result;
|
||||
loadctx_t *ctx = NULL;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
|
||||
REQUIRE(buffer != NULL);
|
||||
|
||||
|
|
@ -1201,7 +1400,7 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top,
|
|||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1215,7 +1414,7 @@ dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top,
|
|||
{
|
||||
isc_result_t result;
|
||||
isc_result_t tresult;
|
||||
loadctx_t *ctx = NULL;
|
||||
dns_loadctx_t *ctx = NULL;
|
||||
|
||||
REQUIRE(buffer != NULL);
|
||||
|
||||
|
|
@ -1240,7 +1439,7 @@ dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top,
|
|||
|
||||
cleanup:
|
||||
if (ctx != NULL)
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1458,30 +1657,36 @@ on_list(dns_rdatalist_t *rdatalist, dns_rdata_t *rdata) {
|
|||
static void
|
||||
load_quantum(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
loadctx_t *ctx;
|
||||
dns_loadctx_t *ctx;
|
||||
|
||||
REQUIRE(event != NULL);
|
||||
ctx = event->ev_arg;
|
||||
REQUIRE(DNS_LCTX_VALID(ctx));
|
||||
|
||||
result = load(&ctx);
|
||||
if (ctx->canceled)
|
||||
result = ISC_R_CANCELED;
|
||||
else
|
||||
result = load(&ctx);
|
||||
if (result == DNS_R_CONTINUE) {
|
||||
isc_task_send(task, &event);
|
||||
} else if (result == ISC_R_SUCCESS && ctx->parent) {
|
||||
/* Pop ctx and continue. */
|
||||
event->ev_arg = ctx->parent;
|
||||
ctx->parent = NULL;
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
isc_task_send(task, &event);
|
||||
} else {
|
||||
(ctx->done)(ctx->done_arg, result);
|
||||
if (ctx->rate_limited)
|
||||
loadmgr_done(ctx, result);
|
||||
else
|
||||
(ctx->done)(ctx->done_arg, result);
|
||||
isc_event_free(&event);
|
||||
loadctx_destroy(&ctx);
|
||||
dns_loadctx_detach(&ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
task_send(loadctx_t *ctx) {
|
||||
task_send(dns_loadctx_t *ctx) {
|
||||
isc_event_t *event;
|
||||
|
||||
event = isc_event_allocate(ctx->mctx, NULL,
|
||||
|
|
@ -1492,3 +1697,181 @@ task_send(loadctx_t *ctx) {
|
|||
isc_task_send(ctx->task, &event);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* DNS load manager.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_loadmgr_create(isc_mem_t *mctx, dns_loadmgr_t **mgrp) {
|
||||
dns_loadmgr_t *mgr;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(mgrp != NULL && *mgrp == NULL);
|
||||
|
||||
mgr = isc_mem_get(mctx, sizeof(*mgr));
|
||||
if (mgr == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
result = isc_mutex_init(&mgr->lock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, mgr, sizeof(*mgr));
|
||||
return (result);
|
||||
}
|
||||
mgr->erefs = 1;
|
||||
mgr->irefs = 0;
|
||||
mgr->limit = 0;
|
||||
mgr->active = 0;
|
||||
mgr->mctx = NULL;
|
||||
isc_mem_attach(mctx, &mgr->mctx);
|
||||
ISC_LIST_INIT(mgr->list);
|
||||
mgr->magic = DNS_LMGR_MAGIC;
|
||||
*mgrp = mgr;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_loadmgr_setlimit(dns_loadmgr_t *mgr, isc_uint32_t limit) {
|
||||
|
||||
REQUIRE(DNS_LMGR_VALID(mgr));
|
||||
|
||||
mgr->limit = limit;
|
||||
}
|
||||
|
||||
isc_uint32_t
|
||||
dns_loadmgr_getlimit(dns_loadmgr_t *mgr) {
|
||||
|
||||
REQUIRE(DNS_LMGR_VALID(mgr));
|
||||
|
||||
return(mgr->limit);
|
||||
}
|
||||
|
||||
void
|
||||
dns_loadmgr_cancel(dns_loadmgr_t *mgr) {
|
||||
|
||||
REQUIRE(DNS_LMGR_VALID(mgr));
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
loadmgr_cancel(mgr);
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
loadmgr_cancel(dns_loadmgr_t *mgr) {
|
||||
dns_loadctx_t *ctx;
|
||||
isc_event_t *event;
|
||||
|
||||
for (ctx = ISC_LIST_HEAD(mgr->list); ctx != NULL; ) {
|
||||
ISC_LIST_UNLINK(mgr->list, ctx, link);
|
||||
event = &ctx->event;
|
||||
event->ev_attributes |= ISC_EVENTATTR_CANCELED;
|
||||
isc_task_send(ctx->task, &event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_loadctx_cancel(dns_loadctx_t *ctx) {
|
||||
isc_event_t *event;
|
||||
|
||||
REQUIRE(DNS_LCTX_VALID(ctx));
|
||||
|
||||
LOCK(&ctx->lock);
|
||||
ctx->canceled = ISC_TRUE;
|
||||
/*
|
||||
* If we are queued to be run dequeue.
|
||||
*/
|
||||
if (ctx->loadmgr != NULL && ISC_LINK_LINKED(ctx, link)) {
|
||||
LOCK(&ctx->loadmgr->lock);
|
||||
ISC_LIST_UNLINK(ctx->loadmgr->list, ctx, link);
|
||||
UNLOCK(&ctx->loadmgr->lock);
|
||||
event = &ctx->event;
|
||||
event->ev_attributes |= ISC_EVENTATTR_CANCELED;
|
||||
isc_task_send(ctx->task, &event);
|
||||
}
|
||||
UNLOCK(&ctx->lock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dns_loadmgr_attach(dns_loadmgr_t *source, dns_loadmgr_t **target) {
|
||||
|
||||
REQUIRE(DNS_LMGR_VALID(source));
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->erefs != 0);
|
||||
source->erefs++;
|
||||
INSIST(source->erefs != 0); /* Overflow? */
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_loadmgr_detach(dns_loadmgr_t **mgrp) {
|
||||
dns_loadmgr_t *mgr;
|
||||
isc_boolean_t destroy = ISC_FALSE;
|
||||
|
||||
REQUIRE(mgrp != NULL);
|
||||
mgr = *mgrp;
|
||||
REQUIRE(DNS_LMGR_VALID(mgr));
|
||||
|
||||
mgrp = NULL;
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
INSIST(mgr->erefs != 0);
|
||||
mgr->erefs--;
|
||||
if (mgr->erefs == 0) {
|
||||
if (mgr->irefs == 0)
|
||||
destroy = ISC_TRUE;
|
||||
else
|
||||
loadmgr_cancel(mgr);
|
||||
}
|
||||
UNLOCK(&mgr->lock);
|
||||
if (destroy)
|
||||
loadmgr_destroy(mgr);
|
||||
}
|
||||
|
||||
static void
|
||||
loadmgr_iattach(dns_loadmgr_t *source, dns_loadmgr_t **target) {
|
||||
|
||||
REQUIRE(DNS_LMGR_VALID(source));
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
source->irefs++;
|
||||
INSIST(source->irefs != 0); /* Overflow? */
|
||||
UNLOCK(&source->lock);
|
||||
|
||||
*target = source;
|
||||
}
|
||||
|
||||
static void
|
||||
loadmgr_idetach(dns_loadmgr_t **mgrp) {
|
||||
dns_loadmgr_t *mgr;
|
||||
isc_boolean_t destroy = ISC_FALSE;
|
||||
|
||||
REQUIRE(mgrp != NULL);
|
||||
mgr = *mgrp;
|
||||
REQUIRE(DNS_LMGR_VALID(mgr));
|
||||
|
||||
mgrp = NULL;
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
INSIST(mgr->irefs != 0);
|
||||
mgr->irefs--;
|
||||
if (mgr->erefs == 0 && mgr->irefs == 0)
|
||||
destroy = ISC_TRUE;
|
||||
UNLOCK(&mgr->lock);
|
||||
if (destroy)
|
||||
loadmgr_destroy(mgr);
|
||||
}
|
||||
|
||||
static void
|
||||
loadmgr_destroy(dns_loadmgr_t *mgr) {
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(mgr->list));
|
||||
|
||||
mgr->magic = 0;
|
||||
DESTROYLOCK(&mgr->lock);
|
||||
isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.c,v 1.78 2000/08/26 01:36:59 bwelling Exp $ */
|
||||
/* $Id: view.c,v 1.79 2000/09/05 03:35:18 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -127,6 +127,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||
view->hints = NULL;
|
||||
view->resolver = NULL;
|
||||
view->adb = NULL;
|
||||
view->loadmgr = NULL;
|
||||
view->requestmgr = NULL;
|
||||
view->mctx = mctx;
|
||||
view->rdclass = rdclass;
|
||||
|
|
@ -228,6 +229,8 @@ destroy(dns_view_t *view) {
|
|||
dns_adb_detach(&view->adb);
|
||||
if (view->resolver != NULL)
|
||||
dns_resolver_detach(&view->resolver);
|
||||
if (view->loadmgr != NULL)
|
||||
dns_loadmgr_detach(&view->loadmgr);
|
||||
if (view->requestmgr != NULL)
|
||||
dns_requestmgr_detach(&view->requestmgr);
|
||||
if (view->task != NULL)
|
||||
|
|
@ -523,6 +526,15 @@ dns_view_setdstport(dns_view_t *view, in_port_t dstport) {
|
|||
view->dstport = dstport;
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_setloadmgr(dns_view_t *view, dns_loadmgr_t *loadmgr) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
if (view->loadmgr != NULL)
|
||||
dns_loadmgr_detach(&view->loadmgr);
|
||||
dns_loadmgr_attach(loadmgr, &view->loadmgr);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
|
|
|
|||
183
lib/dns/zone.c
183
lib/dns/zone.c
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.200 2000/08/31 06:16:42 marka Exp $ */
|
||||
/* $Id: zone.c,v 1.201 2000/09/05 03:35:19 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -30,10 +30,12 @@
|
|||
|
||||
#include <dns/acl.h>
|
||||
#include <dns/adb.h>
|
||||
#include <dns/callbacks.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/events.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/master.h>
|
||||
#include <dns/masterdump.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/name.h>
|
||||
|
|
@ -54,6 +56,7 @@
|
|||
#define NOTIFY_MAGIC 0x4e746679U /* Ntfy */
|
||||
#define STUB_MAGIC 0x53747562U /* Stub */
|
||||
#define ZONEMGR_MAGIC 0x5a6d6772U /* Zmgr */
|
||||
#define LOAD_MAGIC ISC_MAGIC('L','o','a','d')
|
||||
|
||||
#define DNS_ZONE_VALID(zone) \
|
||||
ISC_MAGIC_VALID(zone, ZONE_MAGIC)
|
||||
|
|
@ -63,6 +66,9 @@
|
|||
ISC_MAGIC_VALID(stub, STUB_MAGIC)
|
||||
#define DNS_ZONEMGR_VALID(stub) \
|
||||
ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
|
||||
#define DNS_LOAD_VALID(load) \
|
||||
ISC_MAGIC_VALID(load, LOAD_MAGIC)
|
||||
|
||||
|
||||
#define RANGE(a, b, c) (((a) < (b)) ? (b) : ((a) < (c) ? (a) : (c)))
|
||||
|
||||
|
|
@ -79,6 +85,7 @@
|
|||
|
||||
typedef struct dns_notify dns_notify_t;
|
||||
typedef struct dns_stub dns_stub_t;
|
||||
typedef struct dns_load dns_load_t;
|
||||
|
||||
struct dns_zone {
|
||||
/* Unlocked */
|
||||
|
|
@ -146,6 +153,7 @@ struct dns_zone {
|
|||
dns_severity_t check_names;
|
||||
ISC_LIST(dns_notify_t) notifies;
|
||||
dns_request_t *request;
|
||||
dns_loadctx_t *loadctx;
|
||||
isc_uint32_t maxxfrin;
|
||||
isc_uint32_t maxxfrout;
|
||||
isc_uint32_t idlein;
|
||||
|
|
@ -186,6 +194,7 @@ struct dns_zone {
|
|||
#define DNS_ZONEFLG_NOMASTERS 0x00001000U /* an attempt to refresh a
|
||||
* zone with no masters
|
||||
* occured */
|
||||
#define DNS_ZONEFLG_LOADING 0x00002000U /* load from disk in progress */
|
||||
|
||||
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
|
||||
|
||||
|
|
@ -246,6 +255,18 @@ struct dns_stub {
|
|||
dns_dbversion_t *version;
|
||||
};
|
||||
|
||||
/*
|
||||
* Hold load state.
|
||||
*/
|
||||
struct dns_load {
|
||||
isc_int32_t magic;
|
||||
isc_mem_t *mctx;
|
||||
dns_zone_t *zone;
|
||||
dns_db_t *db;
|
||||
isc_time_t loadtime;
|
||||
dns_rdatacallbacks_t callbacks;
|
||||
};
|
||||
|
||||
static isc_result_t zone_settimer(dns_zone_t *, isc_stdtime_t);
|
||||
static void cancel_refresh(dns_zone_t *);
|
||||
|
||||
|
|
@ -261,7 +282,12 @@ static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
|
|||
isc_boolean_t dump);
|
||||
static isc_result_t default_journal(dns_zone_t *zone);
|
||||
static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
|
||||
static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
|
||||
isc_time_t loadtime, isc_result_t result);
|
||||
static void zone_shutdown(isc_task_t *, isc_event_t *);
|
||||
static void zone_loaddone(void *arg, isc_result_t result);
|
||||
static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
|
||||
isc_time_t loadtime);
|
||||
|
||||
#if 0
|
||||
/* ondestroy example */
|
||||
|
|
@ -389,6 +415,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||
zone->xfr_acl = NULL;
|
||||
zone->check_names = dns_severity_ignore;
|
||||
zone->request = NULL;
|
||||
zone->loadctx = NULL;
|
||||
zone->timer = NULL;
|
||||
zone->idlein = DNS_DEFAULT_IDLEIN;
|
||||
zone->idleout = DNS_DEFAULT_IDLEOUT;
|
||||
|
|
@ -443,6 +470,8 @@ zone_free(dns_zone_t *zone) {
|
|||
isc_timer_detach(&zone->timer);
|
||||
if (zone->request != NULL)
|
||||
dns_request_destroy(&zone->request); /* XXXMPA */
|
||||
if (zone->loadctx != NULL)
|
||||
dns_loadctx_detach(&zone->loadctx);
|
||||
|
||||
INSIST(zone->statelist == NULL);
|
||||
|
||||
|
|
@ -708,9 +737,6 @@ dns_zone_getjournal(dns_zone_t *zone) {
|
|||
isc_result_t
|
||||
dns_zone_load(dns_zone_t *zone) {
|
||||
const char me[] = "dns_zone_load";
|
||||
unsigned int soacount = 0;
|
||||
unsigned int nscount = 0;
|
||||
isc_uint32_t serial, refresh, retry, expire, minimum;
|
||||
isc_result_t result;
|
||||
isc_stdtime_t now;
|
||||
isc_time_t loadtime, filetime;
|
||||
|
|
@ -770,7 +796,88 @@ dns_zone_load(dns_zone_t *zone) {
|
|||
goto cleanup;
|
||||
|
||||
if (!dns_db_ispersistent(db))
|
||||
result = zone_startload(db, zone, loadtime);
|
||||
|
||||
if (result == DNS_R_CONTINUE) {
|
||||
zone->flags |= DNS_ZONEFLG_LOADING;
|
||||
result = ISC_R_SUCCESS;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = zone_postload(zone, db, loadtime, result);
|
||||
|
||||
cleanup:
|
||||
UNLOCK(&zone->lock);
|
||||
if (db != NULL)
|
||||
dns_db_detach(&db);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
|
||||
dns_load_t *load;
|
||||
isc_result_t result;
|
||||
isc_result_t tresult;
|
||||
|
||||
if (zone->view != NULL && zone->view->loadmgr != NULL &&
|
||||
zone->db != NULL) {
|
||||
load = isc_mem_get(zone->mctx, sizeof(*load));
|
||||
if (load == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
load->mctx = NULL;
|
||||
load->zone = NULL;
|
||||
load->db = NULL;
|
||||
load->loadtime = loadtime;
|
||||
load->magic = LOAD_MAGIC;
|
||||
|
||||
isc_mem_attach(zone->mctx, &load->mctx);
|
||||
dns_zone_iattach(zone, &load->zone);
|
||||
dns_db_attach(db, &load->db);
|
||||
dns_rdatacallbacks_init(&load->callbacks);
|
||||
result = dns_db_beginload(db, &load->callbacks.add,
|
||||
&load->callbacks.add_private);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_master_loadfilequota(zone->dbname,
|
||||
dns_db_origin(db),
|
||||
dns_db_origin(db),
|
||||
zone->rdclass, ISC_FALSE,
|
||||
&load->callbacks, zone->task,
|
||||
zone_loaddone, load,
|
||||
zone->view->loadmgr,
|
||||
&zone->loadctx, zone->mctx);
|
||||
if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS) {
|
||||
tresult = dns_db_endload(load->db,
|
||||
&load->callbacks.add_private);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
}
|
||||
} else {
|
||||
result = dns_db_load(db, zone->dbname);
|
||||
}
|
||||
|
||||
return (result);
|
||||
|
||||
cleanup:
|
||||
load->magic = 0;
|
||||
dns_db_detach(&load->db);
|
||||
dns_zone_idetach(&load->zone);
|
||||
isc_mem_detach(&load->mctx);
|
||||
isc_mem_put(zone->mctx, load, sizeof(*load));
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
isc_result_t result)
|
||||
{
|
||||
const char me[] = "dns_zone_load";
|
||||
unsigned int soacount = 0;
|
||||
unsigned int nscount = 0;
|
||||
isc_uint32_t serial, refresh, retry, expire, minimum;
|
||||
isc_stdtime_t now;
|
||||
|
||||
/*
|
||||
* Initiate zone transfer? We may need a error code that
|
||||
|
|
@ -780,8 +887,14 @@ dns_zone_load(dns_zone_t *zone) {
|
|||
if (result != ISC_R_SUCCESS) {
|
||||
if (zone->type == dns_zone_slave ||
|
||||
zone->type == dns_zone_stub) {
|
||||
zone_log(zone, me, ISC_LOG_INFO,
|
||||
"no database file");
|
||||
if (result == ISC_R_FILENOTFOUND)
|
||||
zone_log(zone, me, ISC_LOG_INFO,
|
||||
"no database file");
|
||||
else
|
||||
zone_log(zone, me, ISC_LOG_ERROR,
|
||||
"database %s: dns_db_load failed: %s",
|
||||
zone->dbname,
|
||||
dns_result_totext(result));
|
||||
/* Mark the zone for immediate refresh. */
|
||||
zone->refreshtime = now;
|
||||
result = ISC_R_SUCCESS;
|
||||
|
|
@ -797,6 +910,7 @@ dns_zone_load(dns_zone_t *zone) {
|
|||
"number of nodes in database: %u",
|
||||
dns_db_nodecount(db));
|
||||
zone->loadtime = loadtime;
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(1), "loaded");
|
||||
|
||||
|
|
@ -914,11 +1028,10 @@ dns_zone_load(dns_zone_t *zone) {
|
|||
zone->flags |= DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY;
|
||||
}
|
||||
result = ISC_R_SUCCESS;
|
||||
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
|
||||
(void) zone_settimer(zone, now);
|
||||
|
||||
cleanup:
|
||||
UNLOCK(&zone->lock);
|
||||
if (db != NULL)
|
||||
dns_db_detach(&db);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -1579,7 +1692,7 @@ dns_zone_refresh(dns_zone_t *zone) {
|
|||
}
|
||||
zone->flags |= DNS_ZONEFLG_REFRESH;
|
||||
UNLOCK(&zone->lock);
|
||||
if ((oldflags & DNS_ZONEFLG_REFRESH) != 0)
|
||||
if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
|
@ -3111,6 +3224,9 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||
if (zone->request != NULL)
|
||||
dns_request_cancel(zone->request);
|
||||
|
||||
if (zone->loadctx != NULL)
|
||||
dns_loadctx_cancel(zone->loadctx);
|
||||
|
||||
notify_cancel(zone);
|
||||
|
||||
if (zone->timer != NULL) {
|
||||
|
|
@ -3387,6 +3503,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
dns_rdata_t rdata;
|
||||
isc_result_t result;
|
||||
isc_stdtime_t now;
|
||||
char fromtext[ISC_SOCKADDR_FORMATSIZE];
|
||||
#ifndef NOMINUM_PUBLIC
|
||||
int match = 0;
|
||||
isc_netaddr_t netaddr;
|
||||
|
|
@ -3415,6 +3532,8 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
* first address to check. Return ISC_R_SUCCESS.
|
||||
*/
|
||||
|
||||
isc_sockaddr_format(from, fromtext, sizeof(fromtext));
|
||||
|
||||
/*
|
||||
* We only handle NOTIFY (SOA) at the present.
|
||||
*/
|
||||
|
|
@ -3426,7 +3545,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
UNLOCK(&zone->lock);
|
||||
if (msg->counts[DNS_SECTION_QUESTION] == 0) {
|
||||
zone_log(zone, me, ISC_LOG_NOTICE,
|
||||
"FORMERR no question");
|
||||
"FORMERR no question: %s", fromtext);
|
||||
return (DNS_R_FORMERR);
|
||||
}
|
||||
zone_log(zone, me, ISC_LOG_NOTICE,
|
||||
|
|
@ -3465,7 +3584,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
if (i >= zone->masterscnt) {
|
||||
UNLOCK(&zone->lock);
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3),
|
||||
"REFUSED notify from non master");
|
||||
"REFUSED notify from non master: %s", fromtext);
|
||||
return (DNS_R_REFUSED);
|
||||
}
|
||||
|
||||
|
|
@ -3494,7 +3613,8 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
serial = soa.serial;
|
||||
if (isc_serial_le(serial, zone->serial)) {
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3),
|
||||
"zone up to date");
|
||||
"zone up to date: %s",
|
||||
fromtext);
|
||||
UNLOCK(&zone->lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
@ -3520,7 +3640,8 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
zone->notifyfrom = *from;
|
||||
UNLOCK(&zone->lock);
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3),
|
||||
"refresh in progress, refresh check queued");
|
||||
"refresh in progress, refresh check queued: %s",
|
||||
fromtext);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
isc_stdtime_get(&now);
|
||||
|
|
@ -3528,7 +3649,8 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
|||
zone->notifyfrom = *from;
|
||||
zone_settimer(zone, now);
|
||||
UNLOCK(&zone->lock);
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3), "immediate refresh check queued");
|
||||
zone_log(zone, me, ISC_LOG_DEBUG(3), "immediate refresh check queued: %s",
|
||||
fromtext);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
@ -4081,6 +4203,37 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||
queue_soa_query(zone);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_loaddone(void *arg, isc_result_t result) {
|
||||
static char me[] = "zone_loaddone";
|
||||
dns_load_t *load = arg;
|
||||
dns_zone_t *zone;
|
||||
isc_result_t tresult;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
REQUIRE(DNS_LOAD_VALID(load));
|
||||
zone = load->zone;
|
||||
mctx = load->mctx;
|
||||
|
||||
DNS_ENTER;
|
||||
|
||||
tresult = dns_db_endload(load->db, &load->callbacks.add_private);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
|
||||
LOCK(&load->zone->lock);
|
||||
(void)zone_postload(load->zone, load->db, load->loadtime, result);
|
||||
load->zone->flags &= ~DNS_ZONEFLG_LOADING;
|
||||
UNLOCK(&load->zone->lock);
|
||||
|
||||
load->magic = 0;
|
||||
dns_db_detach(&load->db);
|
||||
dns_loadctx_detach(&zone->loadctx);
|
||||
dns_zone_idetach(&zone);
|
||||
isc_mem_put(mctx, load, sizeof (*load));
|
||||
isc_mem_detach(&mctx);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
|
|
|||
Loading…
Reference in a new issue