master.c revision 6444de08d1aacf7396663b7a82d62eedf534c3d7
/*
* Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
/*! \file */
#include <config.h>
#include <dns/callbacks.h>
#include <dns/fixedname.h>
#include <dns/rdataclass.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/rdatatype.h>
/*!
* 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. */
#define RDLSZ 32
/*%
* RDSZ reflects the number of rdata expected at a give name that can fit into
* 64k.
*/
#define RDSZ 512
#define NBUFS 4
#define MAXWIRESZ 255
/*%
* Target buffer size and minimum target size.
* MINTSIZ must be big enough to hold the largest rdata record.
* \brief
* TSIZ >= MINTSIZ
*/
/*%
* max message size - header - root - type - class - ttl - rdlen
*/
#define MINTSIZ DNS_RDATA_MAXLENGTH
/*%
* Size for tokens in the presentation format,
* The largest tokens are the base64 blocks in KEY and CERT records,
* Largest key allowed is about 1372 bytes but
* there is no fixed upper bound on CERT records.
* 2K is too small for some X.509s, 8K is overkill.
*/
/*%
* Buffers sizes for $GENERATE.
*/
#define DNS_MASTER_LHS 2048
#define DNS_MASTER_RHS MINTSIZ
#define CHECKNAMESFAIL(x) (((x) & DNS_MASTER_CHECKNAMESFAIL) != 0)
typedef struct dns_incctx dns_incctx_t;
/*%
* Master file load state.
*/
struct dns_loadctx {
unsigned int magic;
void *done_arg;
/* Common methods */
const char *filename);
/* Members used by all formats */
/* Members specific to the text format: */
unsigned int options;
/* Members specific to the raw format: */
FILE *f;
/* Which fixed buffers we are using? */
unsigned int loop_cnt; /*% records per quantum,
* 0 => all. */
/* locked by lock */
void *include_arg;
};
struct dns_incctx {
int glue_in_use;
int current_in_use;
int origin_in_use;
unsigned int glue_line;
unsigned int current_line;
};
static isc_result_t
static isc_result_t
static isc_result_t
static isc_result_t
static isc_result_t
static isc_result_t
static isc_result_t
static isc_result_t
dns_name_t *, const char *, unsigned int);
static isc_boolean_t
static dns_rdatalist_t *
static dns_rdata_t *
isc_mem_t *);
static void
static isc_result_t
static void
do { \
switch (result) { \
case ISC_R_SUCCESS: \
break; \
case ISC_R_UNEXPECTED: \
goto insist_and_cleanup; \
default: \
read_till_eol = ISC_TRUE; \
err \
goto next_line; \
} else \
goto log_and_cleanup; \
} \
result = DNS_R_SYNTAX; \
read_till_eol = ISC_TRUE; \
goto next_line; \
} else \
goto log_and_cleanup; \
} \
} while (0)
#define COMMITALL \
do { \
} else if (result != ISC_R_SUCCESS) \
goto insist_and_cleanup; \
} else if (result != ISC_R_SUCCESS) \
goto insist_and_cleanup; \
rdcount = 0; \
rdlcount = 0; \
rdcount_save = rdcount; \
rdlcount_save = rdlcount; \
} while (0)
#define WARNUNEXPECTEDEOF(lexer) \
do { \
if (isc_lex_isfile(lexer)) \
"%s: file does not end with newline", \
source); \
} while (0)
#define EXPECTEOL \
do { \
result = DNS_R_EXTRATOKEN; \
read_till_eol = ISC_TRUE; \
continue; \
} else if (result != ISC_R_SUCCESS) \
goto log_and_cleanup; \
} \
} while (0)
((result != ISC_R_SUCCESS) && \
(result != ISC_R_IOERROR) && \
do { \
} while (0)
result == ISC_R_NOPERM) \
if (result == ISC_R_NOMEMORY) \
dns_result_totext(result)); \
else \
"dns_master_load", \
static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA";
static const dns_name_t in_addr_arpa =
{
{(void *)-1, (void *)-1},
};
static unsigned char ip6_int_data[] = "\003IP6\003INT";
static const dns_name_t ip6_int =
{
{(void *)-1, (void *)-1},
};
static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA";
static const dns_name_t ip6_arpa =
{
{(void *)-1, (void *)-1},
};
static inline isc_result_t
{
if (result != ISC_R_SUCCESS) {
switch (result) {
case ISC_R_NOMEMORY:
return (ISC_R_NOMEMORY);
default:
"dns_master_load: %s:%lu:"
" isc_lex_gettoken() failed: %s",
return (result);
}
/*NOTREACHED*/
}
unsigned long int line;
const char *what;
const char *file;
line--;
what = "line";
} else
what = "file";
"dns_master_load: %s:%lu: unexpected end of %s",
return (ISC_R_UNEXPECTEDEND);
}
return (ISC_R_SUCCESS);
}
void
source->references++;
}
void
lctx->references--;
if (lctx->references == 0)
if (need_destroy)
}
static void
goto again;
}
}
static void
if (result != ISC_R_SUCCESS) {
"isc_stdio_close() failed: %s",
}
}
/* isc_lex_destroy() will close all open streams */
}
static isc_result_t
isc_region_t r;
int i;
return (ISC_R_NOMEMORY);
for (i = 0; i < NBUFS; i++) {
}
ictx->origin_in_use = 0;
dns_name_toregion(origin, &r);
ictx->current_line = 0;
return (ISC_R_SUCCESS);
}
static isc_result_t
{
isc_region_t r;
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (result != ISC_R_SUCCESS)
goto cleanup_ctx;
switch (format) {
default:
INSIST(0);
case dns_masterformat_text:
break;
case dns_masterformat_raw:
break;
case dns_masterformat_map:
break;
}
} else {
if (result != ISC_R_SUCCESS)
goto cleanup_inc;
specials[0] = 1;
}
lctx->default_ttl = 0;
dns_name_toregion(top, &r);
return (ISC_R_SUCCESS);
return (result);
}
static const char *hex = "0123456789abcdef0123456789ABCDEF";
/*%
* Convert value into a nibble sequence from least significant to most
* significant nibble. Zero fill upper most significant nibbles if
* required to make the width.
*
* Returns the number of characters that should have been written without
* counting the terminating NUL.
*/
static unsigned int
unsigned int count = 0;
/*
* This reserve space for the NUL string terminator.
*/
if (length > 0U) {
*numbuf = '\0';
length--;
}
do {
value >>= 4;
if (length > 0U) {
*numbuf = '\0';
length--;
}
if (width > 0)
width--;
count++;
/*
* If width is non zero then we need to add a label seperator.
* If value is non zero then we need to add another label and
* that requires a label seperator.
*/
if (length > 0U) {
*numbuf++ = '.';
*numbuf = '\0';
length--;
}
if (width > 0)
width--;
count++;
}
return (count);
}
static isc_result_t
char fmt[sizeof("%04000000000d")];
char numbuf[128];
char *cp;
char mode[2];
int delta = 0;
unsigned int n;
unsigned int width;
while (*name != '\0') {
if (*name == '$') {
name++;
if (*name == '$') {
if (r.length == 0)
return (ISC_R_NOSPACE);
isc_textregion_consume(&r, 1);
continue;
}
/* Get format specifier. */
if (*name == '{' ) {
switch (n) {
case 1:
break;
case 2:
"%%0%ud", width);
break;
case 3:
break;
default:
return (DNS_R_SYNTAX);
}
if (n >= sizeof(fmt))
return (ISC_R_NOSPACE);
/* Skip past closing brace. */
continue;
}
if (nibblemode)
else
if (n >= sizeof(numbuf))
return (ISC_R_NOSPACE);
while (*cp != '\0') {
if (r.length == 0)
return (ISC_R_NOSPACE);
isc_textregion_consume(&r, 1);
}
} else if (*name == '\\') {
if (r.length == 0)
return (ISC_R_NOSPACE);
isc_textregion_consume(&r, 1);
if (*name == '\0')
continue;
if (r.length == 0)
return (ISC_R_NOSPACE);
isc_textregion_consume(&r, 1);
} else {
if (r.length == 0)
return (ISC_R_NOSPACE);
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
{
char *target_mem = NULL;
goto error_cleanup;
}
{
"%s: %s:%lu: invalid range '%s'",
goto insist_cleanup;
}
if (n == 2)
step = 1;
/*
* Get type.
*/
if (result != ISC_R_SUCCESS) {
"%s: %s:%lu: unknown RR type '%s'",
goto insist_cleanup;
}
if (result != ISC_R_SUCCESS)
goto error_cleanup;
if (result != ISC_R_SUCCESS)
goto error_cleanup;
0, NULL);
if (result != ISC_R_SUCCESS)
goto error_cleanup;
{
char namebuf[DNS_NAME_FORMATSIZE];
/*
* Ignore out-of-zone data.
*/
"%s:%lu: "
"ignoring out-of-zone data (%s)",
continue;
}
if (result != ISC_R_SUCCESS)
goto error_cleanup;
if (result != ISC_R_SUCCESS)
goto error_cleanup;
if (result != ISC_R_SUCCESS)
goto error_cleanup;
}
goto cleanup;
if (result == ISC_R_NOMEMORY)
else
if (target_mem != NULL)
return (result);
}
static void
{
if (*ttlp > 0x7fffffffUL) {
"%s: %s:%lu: "
"$TTL %lu > MAXTTL, "
"setting $TTL to 0",
"dns_master_load",
*ttlp);
*ttlp = 0;
}
}
static isc_result_t
unsigned long line)
{
void (*callback)(struct dns_rdatacallbacks *, const char *, ...);
else
return (ISC_R_NOMEMORY);
/*
* Catch both "1.2.3.4" and "1.2.3.4."
*/
}
if (result != ISC_R_SUCCESS)
"appears to be an address",
return (result);
}
static void
{
if (dns_name_internalwildcard(name)) {
char namebuf[DNS_NAME_FORMATSIZE];
"'%s' contains an non-terminal wildcard",
}
}
static isc_result_t
}
static isc_result_t
isc_uint32_t ttl_offset = 0;
char *include_file = NULL;
int rdlcount = 0;
int rdlcount_save = 0;
int rdatalist_size = 0;
int rdcount = 0;
int rdcount_save = 0;
int rdata_size = 0;
unsigned char *target_mem = NULL;
int target_size = TSIZ;
int new_in_use;
unsigned int loop_cnt = 0;
const char *source = "";
unsigned long line = 0;
unsigned int options = 0;
/*
* Allocate target_size of buffer space. This is greater than twice
* the maximum individual RR data size.
*/
if (target_mem == NULL) {
goto log_and_cleanup;
}
do {
if (read_till_eol)
/* Pop the include stack? */
continue;
}
continue;
}
continue; /* blank line */
}
if (read_till_eol)
continue;
/*
* Still working on the same name.
*/
/*
* "$" Support.
*
* "$ORIGIN" and "$INCLUDE" can both take domain names.
* The processing of "$ORIGIN" and "$INCLUDE" extends
* across the normal domain name processing.
*/
"$TTL") == 0) {
result =
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
continue;
"$INCLUDE") == 0) {
!= 0)
{
"%s: %s:%lu: $INCLUDE not allowed",
"dns_master_load",
goto insist_and_cleanup;
}
if (ttl_offset != 0) {
"%s: %s:%lu: $INCLUDE "
"may not be used with $DATE",
"dns_master_load",
goto insist_and_cleanup;
}
if (include_file != NULL)
DNS_AS_STR(token));
if (include_file == NULL) {
goto log_and_cleanup;
}
/*
* No origin field.
*/
continue;
} else if (result != ISC_R_SUCCESS) {
goto insist_and_cleanup;
}
source =
continue;
}
/*
* There is an origin field. Fall through
* to domain name processing code and do
* the actual inclusion later.
*/
"$DATE") == 0) {
&dump_time64);
dump_time64 = 0;
} else if (result != ISC_R_SUCCESS)
goto log_and_cleanup;
if (dump_time != dump_time64) {
"%s: %s:%lu: $DATE outside epoch",
goto insist_and_cleanup;
}
if (dump_time > current_time) {
"%s: %s:%lu: "
"$DATE in future, using current date",
}
continue;
"$GENERATE") == 0) {
/*
* Lazy cleanup.
*/
/* RANGE */
DNS_AS_STR(token));
goto log_and_cleanup;
}
/* LHS */
goto log_and_cleanup;
}
rdclass = 0;
/* CLASS? */
== ISC_R_SUCCESS) {
}
/* TTL? */
== ISC_R_SUCCESS) {
}
/* CLASS? */
if (rdclass == 0 &&
== ISC_R_SUCCESS)
/* TYPE */
DNS_AS_STR(token));
goto log_and_cleanup;
}
/* RHS */
goto log_and_cleanup;
}
!lctx->default_ttl_known) {
"%s: %s:%lu: no TTL specified",
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
} else if (!explicit_ttl &&
}
/*
* If the class specified does not match the
* zone's class print out a error message and
* exit.
*/
goto bad_class;
}
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
continue;
"$", 1) == 0) {
"%s: %s:%lu: "
"unknown $ directive '%s'",
DNS_AS_STR(token));
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
/*
* Normal processing resumes.
*
* Find a free name buffer.
*/
break;
continue;
} else if (result != ISC_R_SUCCESS)
goto log_and_cleanup;
/*
* Finish $ORIGIN / $INCLUDE processing if required.
*/
if (finish_origin) {
continue;
}
if (finish_include) {
continue;
} else if (result != ISC_R_SUCCESS) {
goto insist_and_cleanup;
}
continue;
}
/*
* "$" Processing Finished
*/
/*
* 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
* state. Linked lists are undone by commit().
*/
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
/*
* 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.
*/
if (current_has_delegation &&
} else {
ictx->current_line);
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
rdcount = 0;
rdlcount = 0;
}
/*
* Check for internal wildcards.
*/
!= 0)
}
{
char namebuf[DNS_NAME_FORMATSIZE];
sizeof(namebuf));
/*
* Ignore out-of-zone data.
*/
"%s:%lu: "
"ignoring out-of-zone data (%s)",
} else
} else {
"%s:%lu: isc_lex_gettoken() returned "
"unexpected token type (%d)",
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
/*
* 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>
*/
type = 0;
rdclass = 0;
if (initialws) {
continue; /* blank line */
}
continue;
}
"%s:%lu: no current owner name",
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
if (ictx->origin_changed) {
char cbuf[DNS_NAME_FORMATSIZE];
char obuf[DNS_NAME_FORMATSIZE];
sizeof(cbuf));
sizeof(obuf));
"%s:%lu: record with inherited "
"owner (%s) immediately after "
}
}
== ISC_R_SUCCESS)
if (result == ISC_R_SUCCESS) {
}
"isc_lex_gettoken() returned unexpected token type");
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
if (rdclass == 0 &&
== ISC_R_SUCCESS)
"isc_lex_gettoken() returned unexpected token type");
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
if (result != ISC_R_SUCCESS) {
"%s:%lu: unknown RR type '%.*s'",
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
/*
* If the class specified does not match the zone's class
* print out a error message and exit.
*/
sizeof(classname1));
sizeof(classname2));
"%s:%lu: class '%s' != "
"zone class '%s'",
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
/*
* RFC1123: MD and MF are not allowed to be loaded from
* master files.
*/
char typename[DNS_RDATATYPE_FORMATSIZE];
"%s:%lu: %s '%s': %s",
"type", typename,
} else
goto insist_and_cleanup;
}
/*
* Find a rdata structure.
*/
if (rdcount == rdata_size) {
goto log_and_cleanup;
}
rdata_size += RDSZ;
}
/*
* Peek at the NS record.
*/
if (type == dns_rdatatype_ns &&
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
}
/*
* Check owner name.
*/
ISC_TRUE);
if (!ok) {
char namebuf[DNS_NAME_FORMATSIZE];
const char *desc;
type == dns_rdatatype_nsec3) {
"%s:%lu: %s: %s",
} else if (result != ISC_R_SUCCESS)
goto cleanup;
} else {
"%s:%lu: %s: %s",
}
}
if (type == dns_rdatatype_ptr &&
}
/*
* Read rdata contents.
*/
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
continue;
}
if (type == dns_rdatatype_soa &&
char namebuf[DNS_NAME_FORMATSIZE];
sizeof(namebuf));
"record not at top of zone (%s)",
continue;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
if (type == dns_rdatatype_rrsig ||
else
covers = 0;
if (type == dns_rdatatype_soa) {
"%s:%lu: no TTL specified; "
"using SOA MINTTL instead",
/*
* Zero TTL's are fine for hints.
*/
} else {
"%s:%lu: no TTL specified; "
"zone rejected",
} else {
goto insist_and_cleanup;
}
}
"%s:%lu: "
"using RFC1035 TTL semantics",
}
NULL);
"%s:%lu: "
"signature has expired",
}
}
}
/*
* Adjust the TTL for $DATE. If the RR has already
* expired, ignore it.
*/
continue;
}
/*
* Find type in rdatalist.
* If it does not exist create new one and prepend to list
* as this will minimise list traversal.
*/
else
break;
}
if (rdlcount == rdatalist_size) {
mctx);
if (new_rdatalist == NULL) {
goto log_and_cleanup;
}
rdatalist_size += RDLSZ;
}
else
link);
"%s:%lu: "
"TTL set to prior TTL (%lu)",
}
{
"dns_master_load: %s:%lu: "
"TTL %d exceeds configured max-zone-ttl %d",
goto log_and_cleanup;
}
else
rdcount++;
/*
* We must have at least 64k as rdlen is 16 bits.
* If we don't commit everything we have so far.
*/
;
/*
* Commit what has not yet been committed.
*/
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
if (!done) {
goto cleanup;
rdatalist_size * sizeof(*rdatalist));
if (target_mem != NULL)
if (include_file != NULL)
return (result);
}
static isc_result_t
isc_region_t r;
int new_in_use;
if (result != ISC_R_SUCCESS)
return (result);
/*
* Push origin_changed.
*/
/* Set current domain. */
break;
}
if (result != ISC_R_SUCCESS)
goto cleanup;
return (ISC_R_SUCCESS);
return (result);
}
static inline isc_result_t
{
if (do_read) {
f, NULL);
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_RANGE);
return (ISC_R_SUCCESS);
}
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
if (result != ISC_R_SUCCESS) {
"isc_stdio_read failed: %s",
return (result);
}
"file format mismatch (not %s)",
? "map"
: "raw");
return (ISC_R_NOTIMPLEMENTED);
}
case 0:
break;
case DNS_RAWFORMAT_VERSION:
break;
default:
"dns_master_load: "
"unsupported file format version");
return (ISC_R_NOTIMPLEMENTED);
}
if (result != ISC_R_SUCCESS) {
"isc_stdio_read failed: %s",
return (result);
}
}
return (ISC_R_SUCCESS);
}
static isc_result_t
"isc_stdio_open() failed: %s",
}
return (result);
}
/*
* Load a map format file, using mmap() to access RBT trees directly
*/
static isc_result_t
if (result != ISC_R_SUCCESS)
return (result);
lctx->f, sizeof(dns_masterrawheader_t));
}
return (result);
}
static isc_result_t
"isc_stdio_open() failed: %s",
}
return (result);
}
static isc_result_t
unsigned int loop_cnt = 0;
unsigned char namebuf[DNS_NAME_MAXWIRE];
unsigned int rdata_size = 0;
int target_size = TSIZ;
unsigned char *target_mem = NULL;
if (result != ISC_R_SUCCESS)
return (result);
}
/*
* Allocate target_size of buffer space. This is greater than twice
* the maximum individual RR data size.
*/
if (target_mem == NULL) {
goto cleanup;
}
/*
* In the following loop, we regard any error fatal regardless of
* whether "MANYERRORS" is set in the context option. This is because
* normal errors should already have been checked at creation time.
* Besides, it is very unlikely that we can recover from an error
* in this format, and so trying to continue parsing erroneous data
* does not really make sense.
*/
for (loop_cnt = 0;
loop_cnt++) {
unsigned int i, rdcount;
/* Read the data length */
sizeof(totallen));
break;
}
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* Validation: the input data must at least contain the common
* header.
*/
sizeof(isc_uint16_t) + sizeof(isc_uint16_t) +
sizeof(isc_uint32_t) + sizeof(isc_uint32_t);
goto cleanup;
}
/*
* The default buffer size should typically be large
* enough to store the entire RRset. We could try to
* allocate enough space if this is not the case, but
* it might cause a hazardous result when "totallen"
* is forged. Thus, we'd rather take an inefficient
* but robust approach in this atypical case: read
* data step by step, and commit partial data when
* necessary. Note that the buffer must be large
* enough to store the "header part", owner name, and
* at least one rdata (however large it is).
*/
} else {
/*
* Typical case. We can read the whole RRset at once
* with the default buffer.
*/
}
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Construct RRset headers */
goto cleanup;
}
/* Owner name: length followed by name */
if (result != ISC_R_SUCCESS)
goto cleanup;
goto cleanup;
}
lctx->f);
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
{
"dns_master_load: "
"TTL %d exceeds configured "
"max-zone-ttl %d",
goto cleanup;
}
/* Rdata contents. */
if (rdcount > rdata_size) {
rdata_size, &head,
goto cleanup;
}
}
for (i = 0; i < rdcount; i++) {
dns_rdata_init(&rdata[i]);
if (sequential_read &&
unsigned int j;
INSIST(i > 0); /* detect an infinite loop */
/* Partial Commit. */
NULL, 0);
for (j = 0; j < i; j++) {
dns_rdata_reset(&rdata[j]);
}
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Rewind the buffer and continue */
rdcount -= i;
goto continue_read;
}
/* rdata length */
if (result != ISC_R_SUCCESS)
goto cleanup;
/* rdata */
if (result != ISC_R_SUCCESS)
goto cleanup;
/*
* It is safe to have the source active region and
* the target available region be the same if
* decompression is disabled (see dctx above) and we
* are not downcasing names (options == 0).
*/
(unsigned int)rdlen);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
/*
* Sanity check. Still having remaining space is not
* necessarily critical, but it very likely indicates broken
* or malformed data.
*/
if (isc_buffer_remaininglength(&target) != 0) {
goto cleanup;
}
/* Commit this RRset. rdatalist will be unlinked. */
for (i = 0; i < rdcount; i++) {
dns_rdata_reset(&rdata[i]);
}
if (result != ISC_R_SUCCESS)
goto cleanup;
}
if (!done) {
if (target_mem != NULL)
}
return (result);
}
{
mctx, dns_masterformat_text, 0));
}
{
}
{
}
{
}
{
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS)
goto cleanup;
return (result);
}
{
}
{
format));
}
{
}
{
}
{
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result == ISC_R_SUCCESS) {
return (DNS_R_CONTINUE);
}
return (result);
}
{
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
return (result);
}
{
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result == ISC_R_SUCCESS) {
return (DNS_R_CONTINUE);
}
return (result);
}
unsigned int options,
{
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS)
goto cleanup;
return (result);
}
unsigned int options,
{
if (result != ISC_R_SUCCESS)
return (result);
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result == ISC_R_SUCCESS) {
return (DNS_R_CONTINUE);
}
return (result);
}
unsigned int options,
{
if (result != ISC_R_SUCCESS)
return (result);
return (result);
}
unsigned int options,
{
if (result != ISC_R_SUCCESS)
return (result);
if (result == ISC_R_SUCCESS) {
return (DNS_R_CONTINUE);
}
return (result);
}
/*
* Grow the slab of dns_rdatalist_t structures.
* Re-link glue and current list.
*/
static dns_rdatalist_t *
{
int rdlcount = 0;
return (NULL);
}
rdlcount++;
}
}
rdlcount++;
}
return (new);
}
/*
* Grow the slab of rdata structs.
* Re-link the current and glue chains.
*/
static dns_rdata_t *
{
int rdcount = 0;
return (NULL);
/*
* Copy current relinking.
*/
}
rdcount++;
}
}
/*
* Copy glue relinking.
*/
}
rdcount++;
}
}
return (new);
}
static isc_uint32_t
}
return (when);
}
/*
* Convert each element from a rdatalist_t to rdataset then call commit.
* Unlink each element as we go.
*/
static isc_result_t
{
char namebuf[DNS_NAME_FORMATSIZE];
void (*error)(struct dns_rdatacallbacks *, const char *, ...);
return (ISC_R_SUCCESS);
do {
== ISC_R_SUCCESS);
/*
* If this is a secure dynamic zone set the re-signing time.
*/
}
&dataset));
if (result == ISC_R_NOMEMORY) {
} else if (result != ISC_R_SUCCESS) {
} else {
"dns_master_load", namebuf,
}
}
else if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
}
/*
* Returns ISC_TRUE if one of the NS rdata's contains 'owner'.
*/
static isc_boolean_t
/*
* Find NS rrset.
*/
break;
}
return (ISC_FALSE);
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static void
else
if (result == DNS_R_CONTINUE) {
} else {
}
}
static isc_result_t
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
void
}
void
}