1999-01-28 05:03:25 +00:00
|
|
|
/*
|
2000-02-03 23:50:32 +00:00
|
|
|
* Copyright (C) 1999, 2000 Internet Software Consortium.
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
1999-01-28 05:03:25 +00:00
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2000-07-27 09:55:03 +00:00
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
|
|
|
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
|
|
|
* INTERNET SOFTWARE CONSORTIUM 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.
|
1999-01-28 05:03:25 +00:00
|
|
|
*/
|
|
|
|
|
2000-12-28 02:31:20 +00:00
|
|
|
/* $Id: master.c,v 1.89 2000/12/28 02:31:20 marka Exp $ */
|
1999-01-28 05:03:25 +00:00
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <isc/event.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <isc/lex.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <isc/magic.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <isc/mem.h>
|
2000-09-19 01:47:53 +00:00
|
|
|
#include <isc/print.h>
|
1999-06-08 10:35:23 +00:00
|
|
|
#include <isc/stdtime.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/string.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <isc/task.h>
|
2000-04-28 01:12:23 +00:00
|
|
|
#include <isc/util.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/callbacks.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <dns/events.h>
|
|
|
|
#include <dns/fixedname.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <dns/master.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/name.h>
|
|
|
|
#include <dns/rdata.h>
|
|
|
|
#include <dns/rdataclass.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <dns/rdatalist.h>
|
|
|
|
#include <dns/rdataset.h>
|
|
|
|
#include <dns/rdatatype.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/result.h>
|
1999-06-08 10:35:23 +00:00
|
|
|
#include <dns/time.h>
|
1999-11-02 13:07:53 +00:00
|
|
|
#include <dns/ttl.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Grow the number of dns_rdatalist_t (RDLSZ) and dns_rdata_t (RDSZ) structures
|
|
|
|
* by these sizes when we need to.
|
|
|
|
*
|
|
|
|
* RDLSZ reflects the number of different types with the same name expected.
|
|
|
|
* RDSZ reflects the number of rdata expected at a give name that can fit into
|
2000-08-01 01:33:37 +00:00
|
|
|
* 64k.
|
1999-03-22 06:21:29 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#define RDLSZ 32
|
|
|
|
#define RDSZ 512
|
|
|
|
|
1999-03-23 00:04:01 +00:00
|
|
|
#define NBUFS 4
|
1999-03-22 06:21:29 +00:00
|
|
|
#define MAXWIRESZ 255
|
|
|
|
|
|
|
|
/*
|
1999-03-24 00:29:54 +00:00
|
|
|
* Target buffer size and minimum target size.
|
2000-02-02 00:36:34 +00:00
|
|
|
* MINTSIZ must be big enough to hold the largest rdata record.
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
1999-03-22 06:21:29 +00:00
|
|
|
* TSIZ >= MINTSIZ
|
|
|
|
*/
|
|
|
|
#define TSIZ (128*1024)
|
|
|
|
/*
|
|
|
|
* max message size - header - root - type - class - ttl - rdlen
|
|
|
|
*/
|
|
|
|
#define MINTSIZ (65535 - 12 - 1 - 2 - 2 - 4 - 2)
|
2000-08-01 01:33:37 +00:00
|
|
|
/*
|
|
|
|
* Size for tokens in the presentation format,
|
1999-10-26 18:05:23 +00:00
|
|
|
* The largest tokens are the base64 blocks in KEY and CERT records,
|
2000-08-01 01:33:37 +00:00
|
|
|
* Largest key allowed is about 1372 bytes but
|
2000-03-22 17:59:13 +00:00
|
|
|
* there is no fixed upper bound on CERT records.
|
|
|
|
* 2K is too small for some X.509s, 8K is overkill.
|
1999-10-26 18:05:23 +00:00
|
|
|
*/
|
|
|
|
#define TOKENSIZ (8*1024)
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2000-09-18 06:50:35 +00:00
|
|
|
#define DNS_MASTER_BUFSZ 2048
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t;
|
|
|
|
|
2000-03-22 19:27:51 +00:00
|
|
|
/*
|
|
|
|
* Master file loading state that persists across $INCLUDEs.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
struct dns_loadctx {
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_uint32_t magic;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
isc_lex_t *lex;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *parent;
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks;
|
|
|
|
isc_task_t *task;
|
|
|
|
dns_loaddonefunc_t done;
|
|
|
|
void *done_arg;
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_boolean_t ttl_known;
|
|
|
|
isc_boolean_t default_ttl_known;
|
|
|
|
isc_boolean_t warn_1035;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_boolean_t age_ttl;
|
2000-10-17 07:22:39 +00:00
|
|
|
isc_boolean_t seen_include;
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_uint32_t ttl;
|
|
|
|
isc_uint32_t default_ttl;
|
|
|
|
dns_rdataclass_t zclass;
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_fixedname_t fixed_top;
|
|
|
|
dns_fixedname_t fixed[NBUFS]; /* working buffers */
|
|
|
|
unsigned int in_use[NBUFS]; /* covert to bitmap? */
|
|
|
|
dns_name_t *top; /* top of zone */
|
|
|
|
dns_name_t *origin;
|
|
|
|
dns_name_t *current;
|
|
|
|
dns_name_t *glue;
|
|
|
|
/* Which fixed buffers we are using? */
|
|
|
|
int glue_in_use;
|
|
|
|
int current_in_use;
|
|
|
|
int origin_in_use;
|
|
|
|
unsigned int loop_cnt; /* records per quantum,
|
|
|
|
* 0 => all. */
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_boolean_t canceled;
|
2000-09-05 03:35:24 +00:00
|
|
|
/* 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;
|
2000-08-15 03:33:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x')
|
|
|
|
#define DNS_LCTX_VALID(ctx) ISC_MAGIC_VALID(ctx, DNS_LCTX_MAGIC)
|
2000-03-22 19:27:51 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
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)
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
static isc_result_t
|
2000-09-05 03:35:24 +00:00
|
|
|
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t **ctxp);
|
2000-05-08 14:38:29 +00:00
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
commit(dns_rdatacallbacks_t *, isc_lex_t *, rdatalist_head_t *, dns_name_t *,
|
|
|
|
dns_name_t *);
|
|
|
|
|
|
|
|
static isc_boolean_t
|
|
|
|
is_glue(rdatalist_head_t *, dns_name_t *);
|
|
|
|
|
|
|
|
static dns_rdatalist_t *
|
|
|
|
grow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *,
|
|
|
|
rdatalist_head_t *, isc_mem_t *mctx);
|
|
|
|
|
|
|
|
static dns_rdata_t *
|
|
|
|
grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
|
|
|
|
isc_mem_t *);
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
static void
|
|
|
|
load_quantum(isc_task_t *task, isc_event_t *event);
|
|
|
|
|
|
|
|
static isc_result_t
|
2000-09-05 03:35:24 +00:00
|
|
|
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);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
#define GETTOKEN(lexer, options, token, eol) \
|
|
|
|
do { \
|
2000-01-22 00:28:00 +00:00
|
|
|
result = gettoken(lexer, options, token, eol, callbacks); \
|
|
|
|
switch (result) { \
|
2000-04-06 22:03:35 +00:00
|
|
|
case ISC_R_SUCCESS: \
|
1999-03-23 00:04:01 +00:00
|
|
|
break; \
|
2000-04-06 22:03:35 +00:00
|
|
|
case ISC_R_UNEXPECTED: \
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup; \
|
1999-03-23 00:04:01 +00:00
|
|
|
default: \
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup; \
|
1999-01-28 05:03:25 +00:00
|
|
|
} \
|
2000-09-17 12:38:47 +00:00
|
|
|
if ((token)->type == isc_tokentype_special) { \
|
|
|
|
result = DNS_R_SYNTAX; \
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup; \
|
2000-09-17 12:38:47 +00:00
|
|
|
} \
|
2000-07-10 05:15:04 +00:00
|
|
|
} while (0)
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
#define COMMITALL \
|
|
|
|
do { \
|
|
|
|
result = commit(callbacks, ctx->lex, ¤t_list, \
|
|
|
|
ctx->current, ctx->top); \
|
|
|
|
if (result != ISC_R_SUCCESS) \
|
2000-11-24 01:51:11 +00:00
|
|
|
goto log_and_cleanup; \
|
2000-08-15 03:33:52 +00:00
|
|
|
result = commit(callbacks, ctx->lex, &glue_list, \
|
|
|
|
ctx->glue, ctx->top); \
|
|
|
|
if (result != ISC_R_SUCCESS) \
|
2000-11-24 01:51:11 +00:00
|
|
|
goto log_and_cleanup; \
|
2000-08-15 03:33:52 +00:00
|
|
|
rdcount = 0; \
|
|
|
|
rdlcount = 0; \
|
|
|
|
isc_buffer_init(&target, target_mem, target_size); \
|
|
|
|
rdcount_save = rdcount; \
|
|
|
|
rdlcount_save = rdlcount; \
|
|
|
|
} while (0)
|
|
|
|
|
2000-07-10 05:15:04 +00:00
|
|
|
#define WARNUNEXPECTEDEOF(lexer) \
|
|
|
|
do { \
|
|
|
|
if (isc_lex_isfile(lexer)) \
|
|
|
|
(*callbacks->warn)(callbacks, \
|
2000-09-18 06:50:35 +00:00
|
|
|
"%s:%lu: file does not end with newline", \
|
2000-07-10 19:07:19 +00:00
|
|
|
isc_lex_getsourcename(lexer), \
|
|
|
|
isc_lex_getsourceline(lexer)); \
|
2000-07-10 05:15:04 +00:00
|
|
|
} while (0)
|
1999-03-23 00:04:01 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
#define CTX_COPYVAR(ctx, new, var) (new)->var = (ctx)->var
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static inline isc_result_t
|
1999-03-23 00:04:01 +00:00
|
|
|
gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token,
|
1999-08-05 22:10:23 +00:00
|
|
|
isc_boolean_t eol, dns_rdatacallbacks_t *callbacks)
|
1999-03-23 00:04:01 +00:00
|
|
|
{
|
|
|
|
isc_result_t result;
|
|
|
|
|
1999-06-09 11:56:45 +00:00
|
|
|
options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE |
|
|
|
|
ISC_LEXOPT_ESCAPE;
|
1999-03-23 00:04:01 +00:00
|
|
|
result = isc_lex_gettoken(lex, options, token);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
switch (result) {
|
|
|
|
case ISC_R_NOMEMORY:
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
1999-03-23 00:04:01 +00:00
|
|
|
default:
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-01-22 01:41:17 +00:00
|
|
|
"isc_lex_gettoken() failed: %s",
|
1999-03-23 00:04:01 +00:00
|
|
|
isc_result_totext(result));
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_UNEXPECTED);
|
1999-03-23 00:04:01 +00:00
|
|
|
}
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
if (eol != ISC_TRUE)
|
|
|
|
if (token->type == isc_tokentype_eol ||
|
|
|
|
token->type == isc_tokentype_eof) {
|
|
|
|
(*callbacks->error)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"dns_master_load: %s:%lu: unexpected end of %s",
|
1999-08-05 22:10:23 +00:00
|
|
|
isc_lex_getsourcename(lex),
|
|
|
|
isc_lex_getsourceline(lex),
|
1999-10-25 18:41:36 +00:00
|
|
|
(token->type ==
|
|
|
|
isc_tokentype_eol) ?
|
1999-08-05 22:10:23 +00:00
|
|
|
"line" : "file");
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_UNEXPECTEDEND);
|
1999-03-23 00:04:01 +00:00
|
|
|
}
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-03-23 00:04:01 +00:00
|
|
|
}
|
1999-01-28 05:03:25 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
|
|
|
|
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;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(ctxp != NULL);
|
|
|
|
ctx = *ctxp;
|
|
|
|
REQUIRE(DNS_LCTX_VALID(ctx));
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
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);
|
2000-08-15 03:33:52 +00:00
|
|
|
*ctxp = NULL;
|
2000-09-05 03:35:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
loadctx_destroy(dns_loadctx_t *ctx) {
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
|
|
|
|
REQUIRE(DNS_LCTX_VALID(ctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
ctx->magic = 0;
|
|
|
|
if (ctx->parent != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx->parent);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
if (ctx->lex != NULL) {
|
|
|
|
isc_lex_close(ctx->lex);
|
|
|
|
isc_lex_destroy(&ctx->lex);
|
|
|
|
}
|
|
|
|
if (ctx->task != NULL)
|
|
|
|
isc_task_detach(&ctx->task);
|
2000-09-05 03:35:24 +00:00
|
|
|
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);
|
2000-08-15 03:33:52 +00:00
|
|
|
mctx = NULL;
|
|
|
|
isc_mem_attach(ctx->mctx, &mctx);
|
|
|
|
isc_mem_detach(&ctx->mctx);
|
|
|
|
isc_mem_put(mctx, ctx, sizeof(*ctx));
|
|
|
|
isc_mem_detach(&mctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
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,
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t **ctxp)
|
2000-08-15 03:33:52 +00:00
|
|
|
{
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_result_t result;
|
|
|
|
isc_region_t r;
|
|
|
|
int i;
|
|
|
|
isc_lexspecials_t specials;
|
|
|
|
|
|
|
|
REQUIRE(ctxp != NULL && *ctxp == NULL);
|
|
|
|
REQUIRE(callbacks != NULL);
|
|
|
|
REQUIRE(callbacks->add != NULL);
|
|
|
|
REQUIRE(callbacks->error != NULL);
|
|
|
|
REQUIRE(callbacks->warn != NULL);
|
|
|
|
REQUIRE(mctx != NULL);
|
|
|
|
REQUIRE(dns_name_isabsolute(top));
|
|
|
|
REQUIRE(dns_name_isabsolute(origin));
|
|
|
|
REQUIRE((task == NULL && done == NULL) ||
|
2000-09-18 06:50:35 +00:00
|
|
|
(task != NULL && done != NULL));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
ctx = isc_mem_get(mctx, sizeof(*ctx));
|
|
|
|
if (ctx == NULL)
|
|
|
|
return (ISC_R_NOMEMORY);
|
2000-09-05 03:35:24 +00:00
|
|
|
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);
|
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
ctx->lex = NULL;
|
|
|
|
result = isc_lex_create(mctx, TOKENSIZ, &ctx->lex);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup_ctx;
|
|
|
|
memset(specials, 0, sizeof specials);
|
|
|
|
specials['('] = 1;
|
|
|
|
specials[')'] = 1;
|
|
|
|
specials['"'] = 1;
|
|
|
|
isc_lex_setspecials(ctx->lex, specials);
|
|
|
|
isc_lex_setcomments(ctx->lex, ISC_LEXCOMMENT_DNSMASTERFILE);
|
|
|
|
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->ttl_known = ISC_FALSE;
|
|
|
|
ctx->ttl = 0;
|
|
|
|
ctx->default_ttl_known = ISC_FALSE;
|
|
|
|
ctx->default_ttl = 0;
|
|
|
|
ctx->warn_1035 = ISC_TRUE; /* XXX Argument? */
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->age_ttl = age_ttl;
|
2000-10-17 07:22:39 +00:00
|
|
|
ctx->seen_include = ISC_FALSE;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->zclass = zclass;
|
|
|
|
|
|
|
|
dns_fixedname_init(&ctx->fixed_top);
|
|
|
|
ctx->top = dns_fixedname_name(&ctx->fixed_top);
|
|
|
|
dns_name_toregion(top, &r);
|
|
|
|
dns_name_fromregion(ctx->top, &r);
|
|
|
|
|
|
|
|
for (i = 0; i < NBUFS; i++) {
|
|
|
|
dns_fixedname_init(&ctx->fixed[i]);
|
|
|
|
ctx->in_use[i] = ISC_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->origin_in_use = 0;
|
|
|
|
ctx->origin = dns_fixedname_name(&ctx->fixed[ctx->origin_in_use]);
|
|
|
|
ctx->in_use[ctx->origin_in_use] = ISC_TRUE;
|
|
|
|
dns_name_toregion(origin, &r);
|
|
|
|
dns_name_fromregion(ctx->origin, &r);
|
|
|
|
|
|
|
|
ctx->glue = NULL;
|
|
|
|
ctx->current = NULL;
|
|
|
|
ctx->glue_in_use = -1;
|
|
|
|
ctx->current_in_use = -1;
|
|
|
|
ctx->loop_cnt = (done != NULL) ? 100 : 0;
|
|
|
|
ctx->callbacks = callbacks;
|
|
|
|
ctx->parent = NULL;
|
|
|
|
ctx->task = NULL;
|
|
|
|
if (task != NULL)
|
|
|
|
isc_task_attach(task, &ctx->task);
|
|
|
|
ctx->done = done;
|
|
|
|
ctx->done_arg = done_arg;
|
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
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;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->mctx = NULL;
|
|
|
|
isc_mem_attach(mctx, &ctx->mctx);
|
2000-09-05 03:35:24 +00:00
|
|
|
ctx->references = 1; /* Implicit attach. */
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->magic = DNS_LCTX_MAGIC;
|
|
|
|
*ctxp = ctx;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
cleanup_ctx:
|
|
|
|
isc_mem_put(mctx, ctx, sizeof(*ctx));
|
|
|
|
return (result);
|
2000-03-22 19:27:51 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2000-09-18 06:50:35 +00:00
|
|
|
static isc_result_t
|
|
|
|
genname(char *name, int it, char *buffer, size_t length) {
|
|
|
|
char fmt[sizeof("%04000000000d")];
|
|
|
|
char numbuf[128];
|
|
|
|
char *cp;
|
|
|
|
char mode;
|
|
|
|
int delta = 0;
|
|
|
|
isc_textregion_t r;
|
|
|
|
unsigned int n;
|
|
|
|
unsigned int width;
|
|
|
|
|
|
|
|
r.base = buffer;
|
|
|
|
r.length = length;
|
|
|
|
|
|
|
|
while (*name != '\0') {
|
|
|
|
if (*name == '$') {
|
|
|
|
name++;
|
2000-11-02 05:18:33 +00:00
|
|
|
if (*name == '$') {
|
|
|
|
if (r.length == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
continue;
|
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
strcpy(fmt, "%d");
|
|
|
|
/* Get format specifier. */
|
|
|
|
if (*name == '{' ) {
|
|
|
|
n = sscanf(name, "{%d,%u,%1[doxX]}",
|
|
|
|
&delta, &width, &mode);
|
|
|
|
switch (n) {
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
n = snprintf(fmt, sizeof(fmt),
|
|
|
|
"%%0%ud", width);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
n = snprintf(fmt, sizeof(fmt),
|
|
|
|
"%%0%u%c", width, mode);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return (DNS_R_SYNTAX);
|
|
|
|
}
|
|
|
|
if (n >= sizeof(fmt))
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
/* Skip past closing brace. */
|
|
|
|
while (*name != '\0' && *name++ != '}')
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
n = snprintf(numbuf, sizeof(numbuf), fmt, it + delta);
|
|
|
|
if (n >= sizeof(numbuf))
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
cp = numbuf;
|
|
|
|
while (*cp != '\0') {
|
|
|
|
if (r.length == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
r.base[0] = *cp++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
}
|
|
|
|
} else if (*name == '\\') {
|
|
|
|
if (r.length == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
if (*name == '\0')
|
|
|
|
continue;
|
|
|
|
if (r.length == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
} else {
|
|
|
|
if (r.length == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (r.length == 0)
|
|
|
|
return (ISC_R_NOSPACE);
|
|
|
|
r.base[0] = '\0';
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
generate(dns_loadctx_t *ctx, char *range, char *lhs, char *gtype, char *rhs) {
|
|
|
|
char *target_mem = NULL;
|
|
|
|
char *lhsbuf = NULL;
|
|
|
|
char *rhsbuf = NULL;
|
|
|
|
dns_fixedname_t ownerfixed;
|
|
|
|
dns_name_t *owner;
|
2000-10-25 04:26:57 +00:00
|
|
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
2000-09-18 06:50:35 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks;
|
|
|
|
dns_rdatalist_t rdatalist;
|
|
|
|
dns_rdatatype_t type;
|
|
|
|
rdatalist_head_t head;
|
|
|
|
int n;
|
|
|
|
int target_size = MINTSIZ; /* only one rdata at a time */
|
|
|
|
isc_buffer_t buffer;
|
|
|
|
isc_buffer_t target;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_textregion_t r;
|
|
|
|
unsigned int start, stop, step, i;
|
|
|
|
|
|
|
|
callbacks = ctx->callbacks;
|
|
|
|
dns_fixedname_init(&ownerfixed);
|
|
|
|
owner = dns_fixedname_name(&ownerfixed);
|
|
|
|
ISC_LIST_INIT(head);
|
|
|
|
|
|
|
|
target_mem = isc_mem_get(ctx->mctx, target_size);
|
|
|
|
rhsbuf = isc_mem_get(ctx->mctx, DNS_MASTER_BUFSZ);
|
|
|
|
lhsbuf = isc_mem_get(ctx->mctx, DNS_MASTER_BUFSZ);
|
|
|
|
if (target_mem == NULL || rhsbuf == NULL || lhsbuf == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto error_cleanup;
|
|
|
|
}
|
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
|
|
|
|
|
|
|
n = sscanf(range, "%u-%u/%u", &start, &stop, &step);
|
|
|
|
if (n < 2 || stop < stop) {
|
|
|
|
(*callbacks->warn)(callbacks,
|
|
|
|
"%s: %s:%lu: invalid range '%s'",
|
|
|
|
"$GENERATE",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
range);
|
|
|
|
result = DNS_R_SYNTAX;
|
|
|
|
goto insist_cleanup;
|
|
|
|
}
|
|
|
|
if (n == 2)
|
|
|
|
step = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get type.
|
|
|
|
*/
|
|
|
|
r.base = gtype;
|
|
|
|
r.length = strlen(gtype);
|
|
|
|
result = dns_rdatatype_fromtext(&type, &r);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
(*callbacks->warn)(callbacks,
|
|
|
|
"%s: %s:%lu: unknown RR type '%s'",
|
|
|
|
"$GENERATE",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
gtype);
|
|
|
|
goto insist_cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case dns_rdatatype_ns:
|
|
|
|
case dns_rdatatype_ptr:
|
|
|
|
case dns_rdatatype_cname:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case dns_rdatatype_a:
|
|
|
|
case dns_rdatatype_aaaa:
|
|
|
|
if (ctx->zclass == dns_rdataclass_in ||
|
|
|
|
ctx->zclass == dns_rdataclass_hs)
|
|
|
|
break;
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
default:
|
|
|
|
(*callbacks->warn)(callbacks,
|
|
|
|
"%s: %s:%lu: unsupported type '%s'",
|
|
|
|
"$GENERATE",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
gtype);
|
|
|
|
result = ISC_R_NOTIMPLEMENTED;
|
|
|
|
goto error_cleanup;
|
|
|
|
}
|
|
|
|
|
2000-12-28 02:31:20 +00:00
|
|
|
ISC_LIST_INIT(rdatalist.rdata);
|
|
|
|
ISC_LINK_INIT(&rdatalist, link);
|
2000-09-18 18:31:06 +00:00
|
|
|
for (i = start; i < stop; i += step) {
|
2000-09-18 06:50:35 +00:00
|
|
|
result = genname(lhs, i, lhsbuf, DNS_MASTER_BUFSZ);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto error_cleanup;
|
|
|
|
result = genname(rhs, i, rhsbuf, DNS_MASTER_BUFSZ);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto error_cleanup;
|
|
|
|
|
|
|
|
isc_buffer_init(&buffer, lhsbuf, strlen(lhsbuf));
|
|
|
|
isc_buffer_add(&buffer, strlen(lhsbuf));
|
|
|
|
isc_buffer_setactive(&buffer, strlen(lhsbuf));
|
|
|
|
result = dns_name_fromtext(owner, &buffer, ctx->origin,
|
|
|
|
ISC_FALSE, NULL);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto error_cleanup;
|
|
|
|
|
|
|
|
isc_buffer_init(&buffer, rhsbuf, strlen(rhsbuf));
|
|
|
|
isc_buffer_add(&buffer, strlen(rhsbuf));
|
|
|
|
isc_buffer_setactive(&buffer, strlen(rhsbuf));
|
|
|
|
|
|
|
|
result = isc_lex_openbuffer(ctx->lex, &buffer);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto error_cleanup;
|
|
|
|
|
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
|
|
|
result = dns_rdata_fromtext(&rdata, ctx->zclass, type,
|
|
|
|
ctx->lex, ctx->origin, ISC_FALSE,
|
2000-11-09 23:55:05 +00:00
|
|
|
ctx->mctx, &target, callbacks);
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_lex_close(ctx->lex);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto error_cleanup;
|
|
|
|
|
|
|
|
rdatalist.type = type;
|
|
|
|
rdatalist.covers = 0;
|
|
|
|
rdatalist.rdclass = ctx->zclass;
|
|
|
|
rdatalist.ttl = ctx->ttl;
|
|
|
|
ISC_LIST_PREPEND(head, &rdatalist, link);
|
|
|
|
ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
|
|
|
|
result = commit(callbacks, ctx->lex, &head, owner,
|
|
|
|
ctx->top);
|
2000-10-25 04:26:57 +00:00
|
|
|
ISC_LIST_UNLINK(rdatalist.rdata, &rdata, link);
|
2000-09-18 06:50:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto error_cleanup;
|
2000-10-31 03:22:05 +00:00
|
|
|
dns_rdata_reset(&rdata);
|
2000-09-18 06:50:35 +00:00
|
|
|
}
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
error_cleanup:
|
|
|
|
if (result == ISC_R_NOMEMORY)
|
|
|
|
(*callbacks->error)(callbacks, "$GENERATE: %s",
|
|
|
|
dns_result_totext(result));
|
|
|
|
else
|
|
|
|
(*callbacks->error)(callbacks, "$GENERATE: %s:%lu: %s",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
dns_result_totext(result));
|
|
|
|
|
|
|
|
insist_cleanup:
|
|
|
|
INSIST(result != ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (target_mem != NULL)
|
|
|
|
isc_mem_put(ctx->mctx, target_mem, target_size);
|
|
|
|
if (lhsbuf != NULL)
|
|
|
|
isc_mem_put(ctx->mctx, lhsbuf, DNS_MASTER_BUFSZ);
|
|
|
|
if (rhsbuf != NULL)
|
|
|
|
isc_mem_put(ctx->mctx, rhsbuf, DNS_MASTER_BUFSZ);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static isc_result_t
|
2000-09-05 03:35:24 +00:00
|
|
|
load(dns_loadctx_t **ctxp) {
|
1999-03-04 02:48:47 +00:00
|
|
|
dns_rdataclass_t rdclass;
|
1999-08-31 22:14:06 +00:00
|
|
|
dns_rdatatype_t type, covers;
|
1999-06-08 10:35:23 +00:00
|
|
|
isc_uint32_t ttl_offset = 0;
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_name_t *new_name;
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_boolean_t current_has_delegation = ISC_FALSE;
|
|
|
|
isc_boolean_t done = ISC_FALSE;
|
1999-01-27 23:57:46 +00:00
|
|
|
isc_boolean_t finish_origin = ISC_FALSE;
|
1999-01-28 01:16:59 +00:00
|
|
|
isc_boolean_t finish_include = ISC_FALSE;
|
1999-01-28 05:03:25 +00:00
|
|
|
isc_boolean_t read_till_eol = ISC_FALSE;
|
2000-07-09 12:52:34 +00:00
|
|
|
isc_boolean_t initialws;
|
1999-01-28 01:16:59 +00:00
|
|
|
char *include_file = NULL;
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_token_t token;
|
2000-08-01 01:33:37 +00:00
|
|
|
isc_result_t result = ISC_R_UNEXPECTED;
|
1999-01-27 13:38:21 +00:00
|
|
|
rdatalist_head_t glue_list;
|
|
|
|
rdatalist_head_t current_list;
|
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdatalist_t *rdatalist = NULL;
|
|
|
|
dns_rdatalist_t *new_rdatalist;
|
|
|
|
int rdlcount = 0;
|
|
|
|
int rdlcount_save = 0;
|
|
|
|
int rdatalist_size = 0;
|
|
|
|
isc_buffer_t buffer;
|
|
|
|
isc_buffer_t target;
|
|
|
|
isc_buffer_t target_save;
|
|
|
|
dns_rdata_t *rdata = NULL;
|
|
|
|
dns_rdata_t *new_rdata;
|
|
|
|
int rdcount = 0;
|
|
|
|
int rdcount_save = 0;
|
|
|
|
int rdata_size = 0;
|
|
|
|
unsigned char *target_mem = NULL;
|
1999-03-22 06:21:29 +00:00
|
|
|
int target_size = TSIZ;
|
1999-01-27 23:17:57 +00:00
|
|
|
int new_in_use;
|
2000-08-15 03:33:52 +00:00
|
|
|
unsigned int loop_cnt = 0;
|
|
|
|
isc_mem_t *mctx;
|
|
|
|
dns_rdatacallbacks_t *callbacks;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx;
|
2000-09-18 06:50:35 +00:00
|
|
|
char *range = NULL;
|
|
|
|
char *lhs = NULL;
|
|
|
|
char *gtype = NULL;
|
|
|
|
char *rhs = NULL;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-02-10 05:25:37 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx = *ctxp;
|
|
|
|
REQUIRE(DNS_LCTX_VALID(ctx));
|
|
|
|
callbacks = ctx->callbacks;
|
|
|
|
mctx = ctx->mctx;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
ISC_LIST_INIT(glue_list);
|
|
|
|
ISC_LIST_INIT(current_list);
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Allocate target_size of buffer space. This is greater than twice
|
|
|
|
* the maximum individual RR data size.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
target_mem = isc_mem_get(mctx, target_size);
|
|
|
|
if (target_mem == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMEMORY;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
1999-01-27 13:38:21 +00:00
|
|
|
target_save = target;
|
1999-03-22 06:21:29 +00:00
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
do {
|
2000-07-09 12:52:34 +00:00
|
|
|
initialws = ISC_FALSE;
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, ISC_LEXOPT_INITIALWS, &token, ISC_TRUE);
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
if (token.type == isc_tokentype_eof) {
|
2000-07-10 05:15:04 +00:00
|
|
|
if (read_till_eol)
|
2000-08-15 03:33:52 +00:00
|
|
|
WARNUNEXPECTEDEOF(ctx->lex);
|
|
|
|
/* Pop the include stack? */
|
|
|
|
if (ctx->parent != NULL) {
|
|
|
|
COMMITALL;
|
|
|
|
*ctxp = ctx->parent;
|
|
|
|
ctx->parent = NULL;
|
|
|
|
CTX_COPYVAR(ctx, *ctxp, ttl_known);
|
|
|
|
CTX_COPYVAR(ctx, *ctxp, default_ttl_known);
|
|
|
|
CTX_COPYVAR(ctx, *ctxp, ttl);
|
|
|
|
CTX_COPYVAR(ctx, *ctxp, default_ttl);
|
|
|
|
CTX_COPYVAR(ctx, *ctxp, warn_1035);
|
2000-10-17 07:22:39 +00:00
|
|
|
CTX_COPYVAR(ctx, *ctxp, seen_include);
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx = *ctxp;
|
|
|
|
continue;
|
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
done = ISC_TRUE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
if (token.type == isc_tokentype_eol) {
|
|
|
|
read_till_eol = ISC_FALSE;
|
1999-01-27 13:38:21 +00:00
|
|
|
continue; /* blank line */
|
1999-01-28 05:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (read_till_eol)
|
|
|
|
continue;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
if (token.type == isc_tokentype_initialws) {
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Still working on the same name.
|
|
|
|
*/
|
2000-07-09 12:52:34 +00:00
|
|
|
initialws = ISC_TRUE;
|
1999-01-27 13:38:21 +00:00
|
|
|
} else if (token.type == isc_tokentype_string) {
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* "$" Support.
|
|
|
|
*
|
|
|
|
* "$ORIGIN" and "$INCLUDE" can both take domain names.
|
|
|
|
* The processing of "$ORIGIN" and "$INCLUDE" extends
|
|
|
|
* across the normal domain name processing.
|
|
|
|
*/
|
|
|
|
|
1999-01-27 23:57:46 +00:00
|
|
|
if (strcasecmp(token.value.as_pointer,
|
|
|
|
"$ORIGIN") == 0) {
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
1999-01-28 05:03:25 +00:00
|
|
|
read_till_eol = ISC_TRUE;
|
1999-01-27 23:57:46 +00:00
|
|
|
finish_origin = ISC_TRUE;
|
1999-01-28 01:16:59 +00:00
|
|
|
} else if (strcasecmp(token.value.as_pointer,
|
2000-09-18 06:50:35 +00:00
|
|
|
"$TTL") == 0) {
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
1999-11-04 01:21:28 +00:00
|
|
|
result =
|
2000-05-08 14:38:29 +00:00
|
|
|
dns_ttl_fromtext(&token.value.as_textregion,
|
|
|
|
&ctx->ttl);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
2000-03-22 19:27:51 +00:00
|
|
|
if (ctx->ttl > 0x7fffffffUL) {
|
1999-02-10 05:25:37 +00:00
|
|
|
(callbacks->warn)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"$TTL %lu > MAXTTL, "
|
|
|
|
"setting $TTL to 0",
|
|
|
|
"dns_master_load",
|
2000-11-27 19:15:39 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
2000-05-24 15:07:59 +00:00
|
|
|
ctx->ttl);
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->ttl = 0;
|
1999-01-28 01:16:59 +00:00
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->default_ttl = ctx->ttl;
|
|
|
|
ctx->default_ttl_known = ISC_TRUE;
|
1999-01-28 05:03:25 +00:00
|
|
|
read_till_eol = ISC_TRUE;
|
1999-01-28 01:16:59 +00:00
|
|
|
continue;
|
|
|
|
} else if (strcasecmp(token.value.as_pointer,
|
|
|
|
"$INCLUDE") == 0) {
|
2000-08-15 03:33:52 +00:00
|
|
|
COMMITALL;
|
1999-06-08 10:35:23 +00:00
|
|
|
if (ttl_offset != 0) {
|
|
|
|
(callbacks->error)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: $INCLUDE "
|
2000-08-01 01:33:37 +00:00
|
|
|
"may not be used with $DATE",
|
2000-05-24 15:07:59 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
2000-09-17 13:08:46 +00:00
|
|
|
result = DNS_R_SYNTAX;
|
|
|
|
goto insist_and_cleanup;
|
1999-06-08 10:35:23 +00:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, ISC_LEXOPT_QSTRING, &token,
|
2000-07-30 20:28:07 +00:00
|
|
|
ISC_FALSE);
|
1999-01-28 01:16:59 +00:00
|
|
|
if (include_file != NULL)
|
|
|
|
isc_mem_free(mctx, include_file);
|
|
|
|
include_file = isc_mem_strdup(mctx,
|
|
|
|
token.value.as_pointer);
|
1999-02-10 05:25:37 +00:00
|
|
|
if (include_file == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMEMORY;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-02-10 05:25:37 +00:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_TRUE);
|
2000-07-10 05:15:04 +00:00
|
|
|
|
1999-01-28 01:16:59 +00:00
|
|
|
if (token.type == isc_tokentype_eol ||
|
|
|
|
token.type == isc_tokentype_eof) {
|
2000-07-10 05:15:04 +00:00
|
|
|
if (token.type == isc_tokentype_eof)
|
2000-08-15 03:33:52 +00:00
|
|
|
WARNUNEXPECTEDEOF(ctx->lex);
|
|
|
|
isc_lex_ungettoken(ctx->lex, &token);
|
2000-03-22 19:27:51 +00:00
|
|
|
/*
|
|
|
|
* No origin field.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
result = pushfile(include_file,
|
|
|
|
ctx->origin,
|
|
|
|
ctxp);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx = *ctxp;
|
1999-01-28 01:16:59 +00:00
|
|
|
continue;
|
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
/*
|
|
|
|
* There is an origin field. Fall through
|
|
|
|
* to domain name processing code and do
|
|
|
|
* the actual inclusion later.
|
|
|
|
*/
|
1999-01-28 05:03:25 +00:00
|
|
|
read_till_eol = ISC_TRUE;
|
1999-01-28 01:16:59 +00:00
|
|
|
finish_include = ISC_TRUE;
|
1999-06-08 10:35:23 +00:00
|
|
|
} else if (strcasecmp(token.value.as_pointer,
|
|
|
|
"$DATE") == 0) {
|
1999-06-24 17:55:41 +00:00
|
|
|
isc_int64_t dump_time64;
|
1999-06-08 10:35:23 +00:00
|
|
|
isc_stdtime_t dump_time, current_time;
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
1999-12-16 23:29:07 +00:00
|
|
|
isc_stdtime_get(¤t_time);
|
1999-06-08 10:35:23 +00:00
|
|
|
result = dns_time64_fromtext(token.value.
|
|
|
|
as_pointer, &dump_time64);
|
2000-01-22 00:28:00 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-10-08 23:26:55 +00:00
|
|
|
dump_time = (isc_stdtime_t)dump_time64;
|
1999-06-08 10:35:23 +00:00
|
|
|
if (dump_time != dump_time64) {
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: "
|
1999-06-08 10:35:23 +00:00
|
|
|
"$DATE outside epoch",
|
2000-05-24 15:07:59 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
2000-09-17 13:08:46 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
|
|
|
goto insist_and_cleanup;
|
1999-06-08 10:35:23 +00:00
|
|
|
}
|
|
|
|
if (dump_time > current_time) {
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: "
|
1999-06-08 10:35:23 +00:00
|
|
|
"$DATE in future, using current date",
|
2000-05-24 15:07:59 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
1999-06-08 10:35:23 +00:00
|
|
|
dump_time = current_time;
|
|
|
|
}
|
|
|
|
ttl_offset = current_time - dump_time;
|
|
|
|
read_till_eol = ISC_TRUE;
|
|
|
|
continue;
|
2000-09-18 06:50:35 +00:00
|
|
|
} else if (strcasecmp(token.value.as_pointer,
|
|
|
|
"$GENERATE") == 0) {
|
|
|
|
/*
|
|
|
|
* Use default ttl if known otherwise
|
|
|
|
* inherit or error.
|
|
|
|
*/
|
|
|
|
if (!ctx->ttl_known &&
|
|
|
|
!ctx->default_ttl_known) {
|
|
|
|
(*callbacks->error)(callbacks,
|
|
|
|
"%s: %s:%lu: no TTL specified",
|
|
|
|
"dns_master_load",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
|
|
|
result = DNS_R_NOTTL;
|
|
|
|
goto insist_and_cleanup;
|
|
|
|
} else if (ctx->default_ttl_known) {
|
|
|
|
ctx->ttl = ctx->default_ttl;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Lazy cleanup.
|
|
|
|
*/
|
|
|
|
if (range != NULL)
|
|
|
|
isc_mem_free(mctx, range);
|
|
|
|
if (lhs != NULL)
|
|
|
|
isc_mem_free(mctx, lhs);
|
|
|
|
if (gtype != NULL)
|
|
|
|
isc_mem_free(mctx, gtype);
|
|
|
|
if (rhs != NULL)
|
|
|
|
isc_mem_free(mctx, rhs);
|
|
|
|
/* range */
|
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
|
|
|
range = isc_mem_strdup(mctx,
|
|
|
|
token.value.as_pointer);
|
|
|
|
if (range == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto log_and_cleanup;
|
|
|
|
}
|
|
|
|
/* LHS */
|
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
|
|
|
lhs = isc_mem_strdup(mctx,
|
|
|
|
token.value.as_pointer);
|
|
|
|
if (lhs == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto log_and_cleanup;
|
|
|
|
}
|
|
|
|
/* TYPE */
|
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
|
|
|
gtype = isc_mem_strdup(mctx,
|
|
|
|
token.value.as_pointer);
|
|
|
|
if (gtype == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto log_and_cleanup;
|
|
|
|
}
|
|
|
|
/* RHS */
|
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
|
|
|
rhs = isc_mem_strdup(mctx,
|
|
|
|
token.value.as_pointer);
|
|
|
|
if (rhs == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto log_and_cleanup;
|
|
|
|
}
|
|
|
|
result = generate(ctx, range, lhs, gtype, rhs);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto insist_and_cleanup;
|
|
|
|
read_till_eol = ISC_TRUE;
|
|
|
|
continue;
|
2000-08-01 01:33:37 +00:00
|
|
|
} else if (strncasecmp(token.value.as_pointer,
|
2000-02-03 19:03:59 +00:00
|
|
|
"$", 1) == 0) {
|
2000-08-01 01:33:37 +00:00
|
|
|
(callbacks->error)(callbacks,
|
2000-11-27 19:15:39 +00:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"unknown $ directive '%s'",
|
|
|
|
"dns_master_load",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
token.value.as_pointer);
|
2000-09-17 13:08:46 +00:00
|
|
|
result = DNS_R_SYNTAX;
|
|
|
|
goto insist_and_cleanup;
|
1999-01-27 23:57:46 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Normal processing resumes.
|
|
|
|
*
|
|
|
|
* Find a free name buffer.
|
|
|
|
*/
|
|
|
|
for (new_in_use = 0; new_in_use < NBUFS ; new_in_use++)
|
2000-08-15 03:33:52 +00:00
|
|
|
if (!ctx->in_use[new_in_use])
|
1999-01-27 23:17:57 +00:00
|
|
|
break;
|
1999-03-22 06:21:29 +00:00
|
|
|
INSIST(new_in_use < NBUFS);
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_fixedname_init(&ctx->fixed[new_in_use]);
|
|
|
|
new_name = dns_fixedname_name(&ctx->fixed[new_in_use]);
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_buffer_init(&buffer, token.value.as_region.base,
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
token.value.as_region.length);
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_buffer_add(&buffer, token.value.as_region.length);
|
|
|
|
isc_buffer_setactive(&buffer,
|
|
|
|
token.value.as_region.length);
|
2000-08-15 03:33:52 +00:00
|
|
|
result = dns_name_fromtext(new_name, &buffer,
|
|
|
|
ctx->origin, ISC_FALSE, NULL);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Finish $ORIGIN / $INCLUDE processing if required.
|
|
|
|
*/
|
1999-01-27 23:57:46 +00:00
|
|
|
if (finish_origin) {
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->origin_in_use != -1)
|
2000-11-27 19:15:39 +00:00
|
|
|
ctx->in_use[ctx->origin_in_use] =
|
|
|
|
ISC_FALSE;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->origin_in_use = new_in_use;
|
|
|
|
ctx->in_use[ctx->origin_in_use] = ISC_TRUE;
|
|
|
|
ctx->origin = new_name;
|
2000-03-22 19:27:51 +00:00
|
|
|
finish_origin = ISC_FALSE;
|
1999-01-27 23:57:46 +00:00
|
|
|
continue;
|
|
|
|
}
|
1999-01-28 01:16:59 +00:00
|
|
|
if (finish_include) {
|
2000-08-15 03:33:52 +00:00
|
|
|
finish_include = ISC_FALSE;
|
2000-11-27 19:15:39 +00:00
|
|
|
result = pushfile(include_file,
|
|
|
|
new_name, ctxp);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx = *ctxp;
|
1999-01-28 01:16:59 +00:00
|
|
|
continue;
|
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* "$" Processing Finished
|
|
|
|
*/
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
/*
|
1999-03-22 06:21:29 +00:00
|
|
|
* If we are processing glue and the new name does
|
|
|
|
* not match the current glue name, commit the glue
|
|
|
|
* and pop stacks leaving us in 'normal' processing
|
1999-03-23 00:04:01 +00:00
|
|
|
* state. Linked lists are undone by commit().
|
1999-01-27 13:38:21 +00:00
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->glue != NULL &&
|
|
|
|
dns_name_compare(ctx->glue, new_name) != 0) {
|
2000-11-27 19:15:39 +00:00
|
|
|
result = commit(callbacks, ctx->lex,
|
|
|
|
&glue_list,
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->glue, ctx->top);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-11-24 01:51:11 +00:00
|
|
|
goto log_and_cleanup;
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->glue_in_use != -1)
|
2000-11-27 19:15:39 +00:00
|
|
|
ctx->in_use[ctx->glue_in_use] =
|
|
|
|
ISC_FALSE;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->glue_in_use = -1;
|
|
|
|
ctx->glue = NULL;
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount = rdcount_save;
|
|
|
|
rdlcount = rdlcount_save;
|
|
|
|
target = target_save;
|
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* If we are in 'normal' processing state and the new
|
|
|
|
* name does not match the current name, see if the
|
|
|
|
* new name is for glue and treat it as such,
|
|
|
|
* otherwise we have a new name so commit what we
|
|
|
|
* have.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
if ((ctx->glue == NULL) && (ctx->current == NULL ||
|
|
|
|
dns_name_compare(ctx->current, new_name) != 0)) {
|
1999-01-27 13:38:21 +00:00
|
|
|
if (current_has_delegation &&
|
2000-08-15 03:33:52 +00:00
|
|
|
is_glue(¤t_list, new_name)) {
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount_save = rdcount;
|
|
|
|
rdlcount_save = rdlcount;
|
|
|
|
target_save = target;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->glue = new_name;
|
|
|
|
ctx->glue_in_use = new_in_use;
|
2000-11-27 19:15:39 +00:00
|
|
|
ctx->in_use[ctx->glue_in_use] =
|
|
|
|
ISC_TRUE;
|
1999-01-27 13:38:21 +00:00
|
|
|
} else {
|
2000-08-15 03:33:52 +00:00
|
|
|
result = commit(callbacks, ctx->lex,
|
1999-02-09 08:02:21 +00:00
|
|
|
¤t_list,
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->current,
|
|
|
|
ctx->top);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-11-24 01:51:11 +00:00
|
|
|
goto log_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount = 0;
|
|
|
|
rdlcount = 0;
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->current_in_use != -1)
|
2000-11-27 19:15:39 +00:00
|
|
|
ctx->in_use[ctx->current_in_use] =
|
|
|
|
ISC_FALSE;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->current_in_use = new_in_use;
|
2000-11-27 19:15:39 +00:00
|
|
|
ctx->in_use[ctx->current_in_use] =
|
|
|
|
ISC_TRUE;
|
2000-08-15 03:33:52 +00:00
|
|
|
ctx->current = new_name;
|
1999-01-27 13:38:21 +00:00
|
|
|
current_has_delegation = ISC_FALSE;
|
1999-01-27 23:17:57 +00:00
|
|
|
isc_buffer_init(&target, target_mem,
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
target_size);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
1999-02-10 05:25:37 +00:00
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s:%lu: isc_lex_gettoken() returned "
|
|
|
|
"unexpeced token type (%d)",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
1999-02-10 05:25:37 +00:00
|
|
|
token.type);
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Find TTL, class and type. Both TTL and class are optional
|
|
|
|
* and may occur in any order if they exist. TTL and class
|
|
|
|
* come before type which must exist.
|
|
|
|
*
|
|
|
|
* [<TTL>] [<class>] <type> <RDATA>
|
|
|
|
* [<class>] [<TTL>] <type> <RDATA>
|
|
|
|
*/
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
type = 0;
|
1999-03-04 02:48:47 +00:00
|
|
|
rdclass = 0;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, initialws);
|
2000-07-09 12:52:34 +00:00
|
|
|
|
|
|
|
if (initialws) {
|
|
|
|
if (token.type == isc_tokentype_eol) {
|
|
|
|
read_till_eol = ISC_FALSE;
|
|
|
|
continue; /* blank line */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (token.type == isc_tokentype_eof) {
|
2000-08-15 03:33:52 +00:00
|
|
|
WARNUNEXPECTEDEOF(ctx->lex);
|
|
|
|
read_till_eol = ISC_FALSE;
|
|
|
|
isc_lex_ungettoken(ctx->lex, &token);
|
2000-07-10 05:15:04 +00:00
|
|
|
continue;
|
2000-07-09 12:52:34 +00:00
|
|
|
}
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->current == NULL) {
|
2000-07-09 12:52:34 +00:00
|
|
|
(*callbacks->error)(callbacks,
|
|
|
|
"%s: %s:%lu: No current owner name",
|
2000-11-27 19:15:39 +00:00
|
|
|
"dns_master_load",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
2000-07-09 12:52:34 +00:00
|
|
|
result = DNS_R_NOOWNER;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
2000-07-09 12:52:34 +00:00
|
|
|
}
|
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-11-02 13:07:53 +00:00
|
|
|
if (dns_rdataclass_fromtext(&rdclass,
|
1999-03-22 06:21:29 +00:00
|
|
|
&token.value.as_textregion)
|
2000-04-06 22:03:35 +00:00
|
|
|
== ISC_R_SUCCESS)
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2000-03-22 19:27:51 +00:00
|
|
|
if (dns_ttl_fromtext(&token.value.as_textregion, &ctx->ttl)
|
2000-04-06 22:03:35 +00:00
|
|
|
== ISC_R_SUCCESS) {
|
2000-03-22 19:27:51 +00:00
|
|
|
if (ctx->ttl > 0x7fffffffUL) {
|
1999-02-10 05:25:37 +00:00
|
|
|
(callbacks->warn)(callbacks,
|
2000-11-27 19:15:39 +00:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"TTL %lu > MAXTTL, "
|
|
|
|
"setting TTL to 0",
|
|
|
|
"dns_master_load",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
ctx->ttl);
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->ttl = 0;
|
1999-01-28 01:16:59 +00:00
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->ttl_known = ISC_TRUE;
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
2000-03-22 19:27:51 +00:00
|
|
|
} else if (!ctx->ttl_known && !ctx->default_ttl_known) {
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* BIND 4 / 8 'USE_SOA_MINIMUM' could be set here.
|
|
|
|
*/
|
1999-02-10 05:25:37 +00:00
|
|
|
(*callbacks->error)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: no TTL specified",
|
1999-08-05 22:10:23 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
1999-02-10 05:25:37 +00:00
|
|
|
result = DNS_R_NOTTL;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
2000-03-22 19:27:51 +00:00
|
|
|
} else if (ctx->default_ttl_known) {
|
|
|
|
ctx->ttl = ctx->default_ttl;
|
|
|
|
} else if (ctx->warn_1035) {
|
1999-03-22 06:21:29 +00:00
|
|
|
(*callbacks->warn)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"using RFC 1035 TTL semantics",
|
1999-08-05 22:10:23 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex));
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->warn_1035 = ISC_FALSE;
|
2000-08-01 01:33:37 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
if (token.type != isc_tokentype_string) {
|
1999-02-10 05:25:37 +00:00
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-01-22 01:41:17 +00:00
|
|
|
"isc_lex_gettoken() returned unexpected token type");
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
if (rdclass == 0 &&
|
1999-10-25 18:41:36 +00:00
|
|
|
dns_rdataclass_fromtext(&rdclass,
|
|
|
|
&token.value.as_textregion)
|
2000-04-06 22:03:35 +00:00
|
|
|
== ISC_R_SUCCESS)
|
2000-08-15 03:33:52 +00:00
|
|
|
GETTOKEN(ctx->lex, 0, &token, ISC_FALSE);
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
if (token.type != isc_tokentype_string) {
|
1999-02-10 05:25:37 +00:00
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-01-22 01:41:17 +00:00
|
|
|
"isc_lex_gettoken() returned unexpected token type");
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
result = dns_rdatatype_fromtext(&type,
|
|
|
|
&token.value.as_textregion);
|
2000-09-18 06:50:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
(*callbacks->warn)(callbacks,
|
2000-11-27 19:15:39 +00:00
|
|
|
"%s: %s:%lu: unknown RR type '%.*s'",
|
|
|
|
"dns_master_load",
|
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
token.value.as_textregion.length,
|
|
|
|
token.value.as_textregion.base);
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
2000-09-18 06:50:35 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* If the class specified does not match the zone's class
|
|
|
|
* print out a error message and exit.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
if (rdclass != 0 && rdclass != ctx->zclass) {
|
2000-11-15 19:06:04 +00:00
|
|
|
char classname1[DNS_RDATACLASS_FORMATSIZE];
|
|
|
|
char classname2[DNS_RDATACLASS_FORMATSIZE];
|
|
|
|
|
|
|
|
dns_rdataclass_format(rdclass, classname1,
|
|
|
|
sizeof(classname1));
|
|
|
|
dns_rdataclass_format(ctx->zclass, classname2,
|
|
|
|
sizeof(classname2));
|
1999-02-10 05:25:37 +00:00
|
|
|
(*callbacks->error)(callbacks,
|
2000-11-15 19:06:04 +00:00
|
|
|
"%s: %s:%lu: class '%s' != "
|
|
|
|
"zone class '%s'",
|
1999-08-05 22:10:23 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
2000-11-15 19:06:04 +00:00
|
|
|
classname1, classname2);
|
1999-02-10 05:25:37 +00:00
|
|
|
result = DNS_R_BADCLASS;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
if (type == dns_rdatatype_ns && ctx->glue == NULL)
|
1999-01-27 13:38:21 +00:00
|
|
|
current_has_delegation = ISC_TRUE;
|
1999-01-28 05:03:25 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->age_ttl) {
|
1999-06-08 10:35:23 +00:00
|
|
|
/*
|
|
|
|
* Adjust the TTL for $DATE. If the RR has already
|
|
|
|
* expired, ignore it without even parsing the rdata
|
2000-08-01 01:33:37 +00:00
|
|
|
* part (good for performance, bad for catching
|
1999-06-08 10:35:23 +00:00
|
|
|
* syntax errors).
|
|
|
|
*/
|
2000-03-22 19:27:51 +00:00
|
|
|
if (ctx->ttl < ttl_offset) {
|
1999-10-25 18:41:36 +00:00
|
|
|
read_till_eol = ISC_TRUE;
|
1999-06-08 10:35:23 +00:00
|
|
|
continue;
|
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->ttl -= ttl_offset;
|
1999-06-08 10:35:23 +00:00
|
|
|
}
|
|
|
|
|
1999-08-31 22:14:06 +00:00
|
|
|
/*
|
|
|
|
* Find a rdata structure.
|
|
|
|
*/
|
|
|
|
if (rdcount == rdata_size) {
|
|
|
|
new_rdata = grow_rdata(rdata_size + RDSZ, rdata,
|
|
|
|
rdata_size, ¤t_list,
|
|
|
|
&glue_list, mctx);
|
|
|
|
if (new_rdata == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMEMORY;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-08-31 22:14:06 +00:00
|
|
|
}
|
|
|
|
rdata_size += RDSZ;
|
|
|
|
rdata = new_rdata;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read rdata contents.
|
|
|
|
*/
|
2000-10-20 02:21:58 +00:00
|
|
|
dns_rdata_init(&rdata[rdcount]);
|
2000-08-15 03:33:52 +00:00
|
|
|
result = dns_rdata_fromtext(&rdata[rdcount], ctx->zclass, type,
|
2000-11-09 23:55:05 +00:00
|
|
|
ctx->lex, ctx->origin, ISC_FALSE, ctx->mctx,
|
|
|
|
&target, callbacks);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
1999-08-31 22:14:06 +00:00
|
|
|
if (type == dns_rdatatype_sig)
|
|
|
|
covers = dns_rdata_covers(&rdata[rdcount]);
|
|
|
|
else
|
|
|
|
covers = 0;
|
|
|
|
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Find type in rdatalist.
|
2000-02-02 00:36:34 +00:00
|
|
|
* If it does not exist create new one and prepend to list
|
1999-03-22 06:21:29 +00:00
|
|
|
* as this will mimimise list traversal.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->glue != NULL)
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(glue_list);
|
|
|
|
else
|
|
|
|
this = ISC_LIST_HEAD(current_list);
|
|
|
|
|
1999-01-27 23:17:57 +00:00
|
|
|
while (this != NULL) {
|
1999-08-31 22:14:06 +00:00
|
|
|
if (this->type == type && this->covers == covers)
|
1999-01-27 13:38:21 +00:00
|
|
|
break;
|
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
if (this == NULL) {
|
|
|
|
if (rdlcount == rdatalist_size) {
|
|
|
|
new_rdatalist =
|
1999-03-22 06:21:29 +00:00
|
|
|
grow_rdatalist(rdatalist_size + RDLSZ,
|
1999-01-27 13:38:21 +00:00
|
|
|
rdatalist,
|
|
|
|
rdatalist_size,
|
|
|
|
¤t_list,
|
|
|
|
&glue_list,
|
|
|
|
mctx);
|
|
|
|
if (new_rdatalist == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMEMORY;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
rdatalist = new_rdatalist;
|
1999-03-22 06:21:29 +00:00
|
|
|
rdatalist_size += RDLSZ;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
this = &rdatalist[rdlcount++];
|
|
|
|
this->type = type;
|
1999-08-31 22:14:06 +00:00
|
|
|
this->covers = covers;
|
2000-08-15 03:33:52 +00:00
|
|
|
this->rdclass = ctx->zclass;
|
2000-03-22 19:27:51 +00:00
|
|
|
this->ttl = ctx->ttl;
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST_INIT(this->rdata);
|
2000-08-15 03:33:52 +00:00
|
|
|
if (ctx->glue != NULL)
|
2000-12-07 20:15:58 +00:00
|
|
|
ISC_LIST_INITANDPREPEND(glue_list, this, link);
|
1999-01-27 13:38:21 +00:00
|
|
|
else
|
2000-12-07 20:15:58 +00:00
|
|
|
ISC_LIST_INITANDPREPEND(current_list, this,
|
2000-10-20 02:21:58 +00:00
|
|
|
link);
|
2000-03-22 19:27:51 +00:00
|
|
|
} else if (this->ttl != ctx->ttl) {
|
1999-02-10 05:25:37 +00:00
|
|
|
(*callbacks->warn)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"TTL set to prior TTL (%lu)",
|
1999-08-05 22:10:23 +00:00
|
|
|
"dns_master_load",
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
1999-02-10 05:25:37 +00:00
|
|
|
this->ttl);
|
2000-03-22 19:27:51 +00:00
|
|
|
ctx->ttl = this->ttl;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
1999-02-10 05:25:37 +00:00
|
|
|
|
2000-09-23 01:05:35 +00:00
|
|
|
ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link);
|
|
|
|
rdcount++;
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We must have at least 64k as rdlen is 16 bits.
|
|
|
|
* If we don't commit everything we have so far.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
if ((target.length - target.used) < MINTSIZ)
|
|
|
|
COMMITALL;
|
2000-11-23 05:04:54 +00:00
|
|
|
} while (!done && (ctx->loop_cnt == 0 || loop_cnt++ < ctx->loop_cnt));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Commit what has not yet been committed.
|
|
|
|
*/
|
2000-11-27 19:15:39 +00:00
|
|
|
result = commit(callbacks, ctx->lex, ¤t_list,
|
|
|
|
ctx->current, ctx->top);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-11-24 01:51:11 +00:00
|
|
|
goto log_and_cleanup;
|
2000-08-15 03:33:52 +00:00
|
|
|
result = commit(callbacks, ctx->lex, &glue_list, ctx->glue, ctx->top);
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-11-24 01:51:11 +00:00
|
|
|
goto log_and_cleanup;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
if (!done) {
|
|
|
|
INSIST(ctx->done != NULL && ctx->task != NULL);
|
|
|
|
result = DNS_R_CONTINUE;
|
2000-10-17 07:22:39 +00:00
|
|
|
} else if (result == ISC_R_SUCCESS && ctx->seen_include)
|
|
|
|
result = DNS_R_SEENINCLUDE;
|
1999-02-10 05:25:37 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2000-09-17 13:08:46 +00:00
|
|
|
log_and_cleanup:
|
2000-09-17 12:38:47 +00:00
|
|
|
if (result == ISC_R_NOMEMORY)
|
|
|
|
(*callbacks->error)(callbacks, "dns_master_load: %s",
|
|
|
|
dns_result_totext(result));
|
|
|
|
else
|
2000-09-17 12:54:44 +00:00
|
|
|
(*callbacks->error)(callbacks, "%s: %s:%lu: %s",
|
|
|
|
"dns_master_load",
|
2000-09-17 12:38:47 +00:00
|
|
|
isc_lex_getsourcename(ctx->lex),
|
|
|
|
isc_lex_getsourceline(ctx->lex),
|
|
|
|
dns_result_totext(result));
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-09-17 13:08:46 +00:00
|
|
|
insist_and_cleanup:
|
|
|
|
INSIST(result != ISC_R_SUCCESS);
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
cleanup:
|
2000-09-18 06:50:35 +00:00
|
|
|
while ((this = ISC_LIST_HEAD(current_list)) != NULL)
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST_UNLINK(current_list, this, link);
|
2000-08-01 01:33:37 +00:00
|
|
|
while ((this = ISC_LIST_HEAD(glue_list)) != NULL)
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST_UNLINK(glue_list, this, link);
|
|
|
|
if (rdatalist != NULL)
|
|
|
|
isc_mem_put(mctx, rdatalist,
|
|
|
|
rdatalist_size * sizeof *rdatalist);
|
|
|
|
if (rdata != NULL)
|
|
|
|
isc_mem_put(mctx, rdata, rdata_size * sizeof *rdata);
|
1999-01-28 01:16:59 +00:00
|
|
|
if (target_mem != NULL)
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_mem_put(mctx, target_mem, target_size);
|
1999-01-28 01:16:59 +00:00
|
|
|
if (include_file != NULL)
|
|
|
|
isc_mem_free(mctx, include_file);
|
2000-09-18 06:50:35 +00:00
|
|
|
if (range != NULL)
|
|
|
|
isc_mem_free(mctx, range);
|
|
|
|
if (lhs != NULL)
|
|
|
|
isc_mem_free(mctx, lhs);
|
|
|
|
if (gtype != NULL)
|
|
|
|
isc_mem_free(mctx, gtype);
|
|
|
|
if (rhs != NULL)
|
|
|
|
isc_mem_free(mctx, rhs);
|
1999-01-27 13:38:21 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-03-22 19:27:51 +00:00
|
|
|
static isc_result_t
|
2000-09-05 03:35:24 +00:00
|
|
|
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t **ctxp) {
|
1999-08-05 22:10:23 +00:00
|
|
|
isc_result_t result;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx;
|
|
|
|
dns_loadctx_t *new = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_region_t r;
|
|
|
|
int new_in_use;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
|
|
|
REQUIRE(master_file != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
REQUIRE(ctxp != NULL);
|
|
|
|
ctx = *ctxp;
|
|
|
|
REQUIRE(DNS_LCTX_VALID(ctx));
|
|
|
|
|
2000-10-17 07:22:39 +00:00
|
|
|
ctx->seen_include = ISC_TRUE;
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = loadctx_create(ctx->mctx, ctx->age_ttl, ctx->top,
|
|
|
|
ctx->zclass, origin, ctx->callbacks,
|
|
|
|
ctx->task, ctx->done, ctx->done_arg,
|
2000-09-18 06:50:35 +00:00
|
|
|
&new);
|
1999-08-05 22:10:23 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
/* Set current domain. */
|
|
|
|
if (ctx->glue != NULL || ctx->current != NULL) {
|
|
|
|
for (new_in_use = 0; new_in_use < NBUFS ; new_in_use++)
|
2000-12-04 04:17:00 +00:00
|
|
|
if (!new->in_use[new_in_use])
|
2000-08-15 03:33:52 +00:00
|
|
|
break;
|
|
|
|
INSIST(new_in_use < NBUFS);
|
|
|
|
new->current_in_use = new_in_use;
|
|
|
|
new->current =
|
|
|
|
dns_fixedname_name(&new->fixed[new->current_in_use]);
|
2000-12-04 04:17:00 +00:00
|
|
|
new->in_use[new->current_in_use] = ISC_TRUE;
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_name_toregion((ctx->glue != NULL) ?
|
|
|
|
ctx->glue : ctx->current, &r);
|
|
|
|
dns_name_fromregion(new->current, &r);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
CTX_COPYVAR(ctx, new, ttl_known);
|
|
|
|
CTX_COPYVAR(ctx, new, default_ttl_known);
|
|
|
|
CTX_COPYVAR(ctx, new, ttl);
|
|
|
|
CTX_COPYVAR(ctx, new, default_ttl);
|
|
|
|
CTX_COPYVAR(ctx, new, warn_1035);
|
2000-10-17 07:22:39 +00:00
|
|
|
CTX_COPYVAR(ctx, new, seen_include);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
result = isc_lex_openfile(new->lex, master_file);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
|
|
|
new->parent = ctx;
|
|
|
|
*ctxp = new;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (new != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&new);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
2000-03-22 19:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_master_loadfile(const char *master_file, dns_name_t *top,
|
|
|
|
dns_name_t *origin,
|
|
|
|
dns_rdataclass_t zclass, isc_boolean_t age_ttl,
|
2000-06-07 03:30:02 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
2000-03-22 19:27:51 +00:00
|
|
|
{
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_result_t result;
|
2000-03-22 19:27:51 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
|
|
|
callbacks, NULL, NULL, NULL, &ctx);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
|
|
|
|
|
|
|
result = isc_lex_openfile(ctx->lex, master_file);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
result = load(&ctx);
|
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ctx != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_master_loadfilequota(const char *master_file, dns_name_t *top,
|
|
|
|
dns_name_t *origin, dns_rdataclass_t zclass,
|
2000-11-27 19:15:39 +00:00
|
|
|
isc_boolean_t age_ttl,
|
|
|
|
dns_rdatacallbacks_t *callbacks,
|
2000-11-08 00:18:18 +00:00
|
|
|
isc_task_t *task, dns_loaddonefunc_t done,
|
2000-09-05 03:35:24 +00:00
|
|
|
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);
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
2000-09-18 06:50:35 +00:00
|
|
|
callbacks, task, done, done_arg, &ctx);
|
2000-09-05 03:35:24 +00:00
|
|
|
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);
|
|
|
|
|
2000-12-01 00:55:16 +00:00
|
|
|
UNUSED(task);
|
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
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;
|
2000-09-18 06:50:35 +00:00
|
|
|
}
|
2000-09-05 03:35:24 +00:00
|
|
|
done:
|
|
|
|
loadmgr_done(ctx, result);
|
|
|
|
isc_event_free(&event);
|
|
|
|
dns_loadctx_detach(&ctx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_master_loadfileinc(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, isc_mem_t *mctx)
|
|
|
|
{
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_result_t result;
|
2000-12-17 23:43:12 +00:00
|
|
|
|
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
|
|
|
callbacks, task, done, done_arg, &ctx);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
|
|
|
|
|
|
|
result = isc_lex_openfile(ctx->lex, master_file);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
|
|
|
|
2000-12-17 23:43:12 +00:00
|
|
|
result = task_send(ctx);
|
|
|
|
if (result == ISC_R_SUCCESS)
|
|
|
|
return (DNS_R_CONTINUE);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ctx != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-08-05 22:10:23 +00:00
|
|
|
dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
|
|
|
dns_rdataclass_t zclass, isc_boolean_t age_ttl,
|
1999-10-25 18:41:36 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
1999-08-05 22:10:23 +00:00
|
|
|
{
|
|
|
|
isc_result_t result;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx = NULL;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
|
|
|
REQUIRE(stream != NULL);
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
|
|
|
callbacks, NULL, NULL, NULL, &ctx);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
2000-03-22 19:27:51 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = isc_lex_openstream(ctx->lex, stream);
|
1999-08-05 22:10:23 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = load(&ctx);
|
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ctx != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_master_loadstreaminc(FILE *stream, 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,
|
|
|
|
isc_mem_t *mctx)
|
|
|
|
{
|
|
|
|
isc_result_t result;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(stream != NULL);
|
2000-12-17 23:43:12 +00:00
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
|
|
|
callbacks, task, done, done_arg, &ctx);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
result = isc_lex_openstream(ctx->lex, stream);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
|
|
|
|
2000-12-17 23:43:12 +00:00
|
|
|
result = task_send(ctx);
|
|
|
|
if (result == ISC_R_SUCCESS)
|
|
|
|
return (DNS_R_CONTINUE);
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
cleanup:
|
|
|
|
if (ctx != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-10-25 18:41:36 +00:00
|
|
|
dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top,
|
|
|
|
dns_name_t *origin, dns_rdataclass_t zclass,
|
|
|
|
isc_boolean_t age_ttl,
|
|
|
|
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
|
1999-08-05 22:10:23 +00:00
|
|
|
{
|
|
|
|
isc_result_t result;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx = NULL;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
|
|
|
REQUIRE(buffer != NULL);
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
|
|
|
callbacks, NULL, NULL, NULL, &ctx);
|
1999-08-05 22:10:23 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
return (result);
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = isc_lex_openbuffer(ctx->lex, buffer);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = load(&ctx);
|
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (ctx != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_master_loadbufferinc(isc_buffer_t *buffer, 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,
|
|
|
|
isc_mem_t *mctx)
|
|
|
|
{
|
|
|
|
isc_result_t result;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(buffer != NULL);
|
2000-12-17 23:43:12 +00:00
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
result = loadctx_create(mctx, age_ttl, top, zclass, origin,
|
|
|
|
callbacks, task, done, done_arg, &ctx);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
1999-08-05 22:10:23 +00:00
|
|
|
return (result);
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
result = isc_lex_openbuffer(ctx->lex, buffer);
|
|
|
|
if (result != ISC_R_SUCCESS)
|
|
|
|
goto cleanup;
|
|
|
|
|
2000-12-17 23:43:12 +00:00
|
|
|
result = task_send(ctx);
|
|
|
|
if (result == ISC_R_SUCCESS)
|
|
|
|
return (DNS_R_CONTINUE);
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
cleanup:
|
|
|
|
if (ctx != NULL)
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Grow the slab of dns_rdatalist_t structures.
|
|
|
|
* Re-link glue and current list.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
static dns_rdatalist_t *
|
|
|
|
grow_rdatalist(int new_len, dns_rdatalist_t *old, int old_len,
|
|
|
|
rdatalist_head_t *current, rdatalist_head_t *glue,
|
|
|
|
isc_mem_t *mctx)
|
|
|
|
{
|
|
|
|
dns_rdatalist_t *new;
|
|
|
|
int rdlcount = 0;
|
|
|
|
ISC_LIST(dns_rdatalist_t) save;
|
|
|
|
dns_rdatalist_t *this;
|
|
|
|
|
|
|
|
new = isc_mem_get(mctx, new_len * sizeof *new);
|
|
|
|
if (new == NULL)
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
ISC_LIST_INIT(save);
|
|
|
|
this = ISC_LIST_HEAD(*current);
|
|
|
|
while ((this = ISC_LIST_HEAD(*current)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(*current, this, link);
|
|
|
|
ISC_LIST_APPEND(save, this, link);
|
|
|
|
}
|
|
|
|
while ((this = ISC_LIST_HEAD(save)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(save, this, link);
|
|
|
|
new[rdlcount] = *this;
|
|
|
|
ISC_LIST_APPEND(*current, &new[rdlcount], link);
|
|
|
|
rdlcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LIST_INIT(save);
|
|
|
|
this = ISC_LIST_HEAD(*glue);
|
|
|
|
while ((this = ISC_LIST_HEAD(*glue)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(*glue, this, link);
|
|
|
|
ISC_LIST_APPEND(save, this, link);
|
|
|
|
}
|
|
|
|
while ((this = ISC_LIST_HEAD(save)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(save, this, link);
|
|
|
|
new[rdlcount] = *this;
|
|
|
|
ISC_LIST_APPEND(*glue, &new[rdlcount], link);
|
|
|
|
rdlcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
INSIST(rdlcount == old_len);
|
|
|
|
if (old != NULL)
|
|
|
|
isc_mem_put(mctx, old, old_len * sizeof *old);
|
|
|
|
return (new);
|
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Grow the slab of rdata structs.
|
|
|
|
* Re-link the current and glue chains.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
static dns_rdata_t *
|
|
|
|
grow_rdata(int new_len, dns_rdata_t *old, int old_len,
|
|
|
|
rdatalist_head_t *current, rdatalist_head_t *glue,
|
|
|
|
isc_mem_t *mctx)
|
|
|
|
{
|
|
|
|
dns_rdata_t *new;
|
|
|
|
int rdcount = 0;
|
|
|
|
ISC_LIST(dns_rdata_t) save;
|
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdata_t *rdata;
|
|
|
|
|
|
|
|
new = isc_mem_get(mctx, new_len * sizeof *new);
|
|
|
|
if (new == NULL)
|
|
|
|
return (NULL);
|
|
|
|
memset(new, 0, new_len * sizeof *new);
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy current relinking.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(*current);
|
|
|
|
while (this != NULL) {
|
|
|
|
ISC_LIST_INIT(save);
|
|
|
|
while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(this->rdata, rdata, link);
|
|
|
|
ISC_LIST_APPEND(save, rdata, link);
|
|
|
|
}
|
|
|
|
while ((rdata = ISC_LIST_HEAD(save)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(save, rdata, link);
|
|
|
|
new[rdcount] = *rdata;
|
|
|
|
ISC_LIST_APPEND(this->rdata, &new[rdcount], link);
|
|
|
|
rdcount++;
|
|
|
|
}
|
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Copy glue relinking.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(*glue);
|
|
|
|
while (this != NULL) {
|
|
|
|
ISC_LIST_INIT(save);
|
|
|
|
while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(this->rdata, rdata, link);
|
|
|
|
ISC_LIST_APPEND(save, rdata, link);
|
|
|
|
}
|
|
|
|
while ((rdata = ISC_LIST_HEAD(save)) != NULL) {
|
|
|
|
ISC_LIST_UNLINK(save, rdata, link);
|
|
|
|
new[rdcount] = *rdata;
|
|
|
|
ISC_LIST_APPEND(this->rdata, &new[rdcount], link);
|
|
|
|
rdcount++;
|
|
|
|
}
|
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
|
|
|
INSIST(rdcount == old_len);
|
|
|
|
if (old != NULL)
|
|
|
|
isc_mem_put(mctx, old, old_len * sizeof *old);
|
|
|
|
return (new);
|
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Convert each element from a rdatalist_t to rdataset then call commit.
|
|
|
|
* Unlink each element as we go.
|
|
|
|
*/
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static isc_result_t
|
2000-04-28 23:15:24 +00:00
|
|
|
commit(dns_rdatacallbacks_t *callbacks, isc_lex_t *lex,
|
|
|
|
rdatalist_head_t *head, dns_name_t *owner, dns_name_t *top)
|
1999-01-28 05:03:25 +00:00
|
|
|
{
|
1999-01-27 13:38:21 +00:00
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdataset_t dataset;
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t result;
|
2000-03-29 21:01:30 +00:00
|
|
|
isc_boolean_t ignore = ISC_FALSE;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-03-29 21:01:30 +00:00
|
|
|
this = ISC_LIST_HEAD(*head);
|
|
|
|
if (this == NULL)
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2000-03-29 21:01:30 +00:00
|
|
|
if (!dns_name_issubdomain(owner, top)) {
|
|
|
|
/*
|
|
|
|
* Ignore out-of-zone data.
|
|
|
|
*/
|
2000-04-28 23:15:24 +00:00
|
|
|
(callbacks->warn)(callbacks,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"ignoring out-of-zone data",
|
|
|
|
"dns_master_load",
|
2000-04-28 23:15:24 +00:00
|
|
|
isc_lex_getsourcename(lex),
|
|
|
|
isc_lex_getsourceline(lex));
|
2000-03-29 21:01:30 +00:00
|
|
|
ignore = ISC_TRUE;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
2000-03-29 21:01:30 +00:00
|
|
|
do {
|
|
|
|
if (!ignore) {
|
|
|
|
dns_rdataset_init(&dataset);
|
|
|
|
dns_rdatalist_tordataset(this, &dataset);
|
2000-04-20 18:47:21 +00:00
|
|
|
dataset.trust = dns_trust_ultimate;
|
2000-03-29 21:01:30 +00:00
|
|
|
result = ((*callbacks->add)(callbacks->add_private,
|
|
|
|
owner,
|
|
|
|
&dataset));
|
2000-04-06 22:03:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS)
|
2000-03-29 21:01:30 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
ISC_LIST_UNLINK(*head, this, link);
|
|
|
|
this = ISC_LIST_HEAD(*head);
|
|
|
|
} while (this != NULL);
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Returns ISC_TRUE if one of the NS rdata's contains 'owner'.
|
|
|
|
*/
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
static isc_boolean_t
|
|
|
|
is_glue(rdatalist_head_t *head, dns_name_t *owner) {
|
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdata_t *rdata;
|
|
|
|
isc_region_t region;
|
|
|
|
dns_name_t name;
|
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Find NS rrset.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(*head);
|
|
|
|
while (this != NULL) {
|
1999-02-04 06:38:43 +00:00
|
|
|
if (this->type == dns_rdatatype_ns)
|
1999-01-27 13:38:21 +00:00
|
|
|
break;
|
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
|
|
|
if (this == NULL)
|
|
|
|
return (ISC_FALSE);
|
|
|
|
|
|
|
|
rdata = ISC_LIST_HEAD(this->rdata);
|
|
|
|
while (rdata != NULL) {
|
|
|
|
dns_name_init(&name, NULL);
|
|
|
|
dns_rdata_toregion(rdata, ®ion);
|
|
|
|
dns_name_fromregion(&name, ®ion);
|
|
|
|
if (dns_name_compare(&name, owner) == 0)
|
|
|
|
return (ISC_TRUE);
|
1999-01-27 23:17:57 +00:00
|
|
|
rdata = ISC_LIST_NEXT(rdata, link);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
return (ISC_FALSE);
|
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
static void
|
|
|
|
load_quantum(isc_task_t *task, isc_event_t *event) {
|
|
|
|
isc_result_t result;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_t *ctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(event != NULL);
|
|
|
|
ctx = event->ev_arg;
|
|
|
|
REQUIRE(DNS_LCTX_VALID(ctx));
|
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
if (ctx->canceled)
|
|
|
|
result = ISC_R_CANCELED;
|
|
|
|
else
|
|
|
|
result = load(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
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;
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_task_send(task, &event);
|
|
|
|
} else {
|
2000-09-05 03:35:24 +00:00
|
|
|
if (ctx->rate_limited)
|
|
|
|
loadmgr_done(ctx, result);
|
|
|
|
else
|
|
|
|
(ctx->done)(ctx->done_arg, result);
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_event_free(&event);
|
2000-09-05 03:35:24 +00:00
|
|
|
dns_loadctx_detach(&ctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2000-09-05 03:35:24 +00:00
|
|
|
task_send(dns_loadctx_t *ctx) {
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_event_t *event;
|
|
|
|
|
2000-08-24 19:13:13 +00:00
|
|
|
event = isc_event_allocate(ctx->mctx, NULL,
|
2000-08-15 03:33:52 +00:00
|
|
|
DNS_EVENT_MASTERQUANTUM,
|
|
|
|
load_quantum, ctx, sizeof(*event));
|
|
|
|
if (event == NULL)
|
|
|
|
return (ISC_R_NOMEMORY);
|
|
|
|
isc_task_send(ctx->task, &event);
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
2000-09-05 03:35:24 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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));
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
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));
|
|
|
|
}
|