master.c revision 2a12984ce69f7f49dc3aeef1b216e0c7c93373ac
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Copyright (C) 1999-2003 Internet Software Consortium.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Permission to use, copy, modify, and/or distribute this software for any
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * purpose with or without fee is hereby granted, provided that the above
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * copyright notice and this permission notice appear in all copies.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * PERFORMANCE OF THIS SOFTWARE.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * by these sizes when we need to.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki/*% RDLSZ reflects the number of different types with the same name expected. */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * RDSZ reflects the number of rdata expected at a give name that can fit into
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Target buffer size and minimum target size.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * MINTSIZ must be big enough to hold the largest rdata record.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * TSIZ >= MINTSIZ
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * max message size - header - root - type - class - ttl - rdlen
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Size for tokens in the presentation format,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * The largest tokens are the base64 blocks in KEY and CERT records,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Largest key allowed is about 1372 bytes but
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * there is no fixed upper bound on CERT records.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * 2K is too small for some X.509s, 8K is overkill.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Buffers sizes for $GENERATE.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki#define CHECKNAMESFAIL(x) (((x) & DNS_MASTER_CHECKNAMESFAIL) != 0)
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickitypedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t;
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * Master file load state.
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki unsigned int magic;
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /* Common methods */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki isc_result_t (*openfile)(dns_loadctx_t *lctx,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /* Members used by all formats */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /* Members specific to the text format: */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /* Members specific to the raw format: */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /* Which fixed buffers we are using? */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki unsigned int loop_cnt; /*% records per quantum,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki * 0 => all. */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /* locked by lock */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki dns_fixedname_t fixed[NBUFS]; /* working buffers */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki unsigned int in_use[NBUFS]; /* covert to bitmap? */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki#define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x')
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki#define DNS_LCTX_VALID(lctx) ISC_MAGIC_VALID(lctx, DNS_LCTX_MAGIC)
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki#define DNS_AS_STR(t) ((t).value.as_textregion.base)
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickiopenfile_text(dns_loadctx_t *lctx, const char *master_file);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickiopenfile_raw(dns_loadctx_t *lctx, const char *master_file);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickiopenfile_map(dns_loadctx_t *lctx, const char *master_file);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickipushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickicommit(dns_rdatacallbacks_t *, dns_loadctx_t *, rdatalist_head_t *,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki dns_name_t *, const char *, unsigned int);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickigrow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickigrow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickiload_quantum(isc_task_t *task, isc_event_t *event);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki#define GETTOKENERR(lexer, options, token, eol, err) \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki result = gettoken(lexer, options, token, eol, callbacks); \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki if ((token)->type == isc_tokentype_special) { \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki#define GETTOKEN(lexer, options, token, eol) \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki GETTOKENERR(lexer, options, token, eol, {} )
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki result = commit(callbacks, lctx, ¤t_list, \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki ictx->current, source, ictx->current_line); \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki result = commit(callbacks, lctx, &glue_list, \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki isc_buffer_init(&target, target_mem, target_size); \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki "%s: file does not end with newline", \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki ((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki result == ISC_R_IOERROR || result == ISC_R_TOOMANYOPENFILES || \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki (*callbacks->error)(callbacks, "%s: %s:%lu: %s: %s", \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki (*callbacks->error)(callbacks, "dns_master_load: %s", \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki (*callbacks->error)(callbacks, "%s: %s:%lu: %s", \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki "dns_master_load", \
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickistatic unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA";
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickistatic unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 };
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickistatic unsigned char ip6_int_data[] = "\003IP6\003INT";
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickistatic unsigned char ip6_int_offsets[] = { 0, 4, 8 };
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickistatic unsigned char ip6_arpa_data[] = "\003IP6\004ARPA";
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickistatic unsigned char ip6_arpa_offsets[] = { 0, 4, 9 };
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickigettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token,
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki isc_boolean_t eol, dns_rdatacallbacks_t *callbacks)
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE |
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki result = isc_lex_gettoken(lex, options, token);
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki "dns_master_load: %s:%lu:"
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki " isc_lex_gettoken() failed: %s",
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki /*NOTREACHED*/
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki unsigned long int line;
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki "dns_master_load: %s:%lu: unexpected end of %s",
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickidns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki INSIST(source->references != 0); /* Overflow? */
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecickiincctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) {
19d80ce5844e00a021643759adcbe27c11b485a0Witold Krecicki "isc_stdio_close() failed: %s",
static isc_result_t
isc_region_t r;
return (ISC_R_NOMEMORY);
for (i = 0; i < NBUFS; i++) {
return (ISC_R_SUCCESS);
static isc_result_t
isc_region_t r;
return (ISC_R_NOMEMORY);
return (result);
goto cleanup_ctx;
switch (format) {
INSIST(0);
case dns_masterformat_text:
case dns_masterformat_raw:
case dns_masterformat_map:
goto cleanup_inc;
return (ISC_R_SUCCESS);
return (result);
unsigned int count = 0;
if (length > 0U) {
length--;
if (length > 0U) {
length--;
if (width > 0)
width--;
count++;
if (length > 0U) {
length--;
if (width > 0)
width--;
count++;
return (count);
static isc_result_t
char *cp;
int delta = 0;
unsigned int width;
name++;
if (r.length == 0)
return (ISC_R_NOSPACE);
return (DNS_R_SYNTAX);
if (n >= sizeof(fmt))
return (ISC_R_NOSPACE);
if (nibblemode)
if (n >= sizeof(numbuf))
return (ISC_R_NOSPACE);
if (r.length == 0)
return (ISC_R_NOSPACE);
if (r.length == 0)
return (ISC_R_NOSPACE);
if (r.length == 0)
return (ISC_R_NOSPACE);
if (r.length == 0)
return (ISC_R_NOSPACE);
if (r.length == 0)
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
static isc_result_t
goto error_cleanup;
goto insist_cleanup;
goto insist_cleanup;
goto error_cleanup;
goto error_cleanup;
0, NULL);
goto error_cleanup;
goto error_cleanup;
goto error_cleanup;
goto error_cleanup;
goto cleanup;
return (result);
*ttlp);
*ttlp = 0;
static isc_result_t
unsigned long line)
return (ISC_R_NOMEMORY);
return (result);
static isc_result_t
static isc_result_t
int rdlcount = 0;
int rdlcount_save = 0;
int rdatalist_size = 0;
int rdcount = 0;
int rdcount_save = 0;
int rdata_size = 0;
int new_in_use;
unsigned int loop_cnt = 0;
unsigned long line = 0;
unsigned int options = 0;
goto log_and_cleanup;
if (read_till_eol)
if (read_till_eol)
result =
goto insist_and_cleanup;
goto insist_and_cleanup;
if (ttl_offset != 0) {
goto insist_and_cleanup;
goto log_and_cleanup;
goto insist_and_cleanup;
source =
&dump_time64);
dump_time64 = 0;
goto log_and_cleanup;
goto insist_and_cleanup;
goto log_and_cleanup;
goto log_and_cleanup;
rdclass = 0;
== ISC_R_SUCCESS) {
== ISC_R_SUCCESS) {
if (rdclass == 0 &&
== ISC_R_SUCCESS)
goto log_and_cleanup;
goto log_and_cleanup;
goto insist_and_cleanup;
} else if (!explicit_ttl &&
goto bad_class;
goto insist_and_cleanup;
goto insist_and_cleanup;
goto log_and_cleanup;
if (finish_origin) {
if (finish_include) {
goto insist_and_cleanup;
goto insist_and_cleanup;
if (current_has_delegation &&
goto insist_and_cleanup;
rdcount = 0;
rdlcount = 0;
sizeof(namebuf));
goto insist_and_cleanup;
type = 0;
rdclass = 0;
if (initialws) {
goto insist_and_cleanup;
sizeof(cbuf));
sizeof(obuf));
== ISC_R_SUCCESS)
goto insist_and_cleanup;
if (rdclass == 0 &&
== ISC_R_SUCCESS)
goto insist_and_cleanup;
goto insist_and_cleanup;
sizeof(classname1));
sizeof(classname2));
goto insist_and_cleanup;
goto insist_and_cleanup;
goto log_and_cleanup;
goto insist_and_cleanup;
ISC_TRUE);
if (!ok) {
const char *desc;
goto cleanup;
goto insist_and_cleanup;
sizeof(namebuf));
goto insist_and_cleanup;
covers = 0;
goto insist_and_cleanup;
NULL);
mctx);
goto log_and_cleanup;
link);
goto log_and_cleanup;
rdcount++;
goto insist_and_cleanup;
goto insist_and_cleanup;
if (!done) {
goto cleanup;
return (result);
static isc_result_t
isc_region_t r;
int new_in_use;
return (result);
goto cleanup;
return (ISC_R_SUCCESS);
return (result);
static inline isc_result_t
if (do_read) {
f, NULL);
return (result);
return (ISC_R_RANGE);
return (ISC_R_SUCCESS);
static isc_result_t
return (ISC_R_NOTIMPLEMENTED);
return (result);
return (ISC_R_NOTIMPLEMENTED);
case DNS_RAWFORMAT_VERSION:
return (ISC_R_NOTIMPLEMENTED);
return (result);
return (ISC_R_SUCCESS);
static isc_result_t
return (result);
static isc_result_t
return (result);
return (result);
static isc_result_t
return (result);
static isc_result_t
unsigned int loop_cnt = 0;
unsigned int rdata_size = 0;
return (result);
goto cleanup;
for (loop_cnt = 0;
loop_cnt++) {
unsigned int i, rdcount;
sizeof(totallen));
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
lctx->f);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
for (i = 0; i < rdcount; i++) {
if (sequential_read &&
NULL, 0);
goto cleanup;
rdcount -= i;
goto continue_read;
goto cleanup;
goto cleanup;
(unsigned int)rdlen);
goto cleanup;
goto cleanup;
for (i = 0; i < rdcount; i++) {
goto cleanup;
if (!done) {
return (result);
return (result);
goto cleanup;
return (result);
format));
return (result);
goto cleanup;
return (DNS_R_CONTINUE);
return (result);
goto cleanup;
goto cleanup;
return (result);
goto cleanup;
goto cleanup;
return (DNS_R_CONTINUE);
return (result);
unsigned int options,
return (result);
goto cleanup;
return (result);
unsigned int options,
return (result);
goto cleanup;
return (DNS_R_CONTINUE);
return (result);
unsigned int options,
return (result);
return (result);
unsigned int options,
return (result);
return (DNS_R_CONTINUE);
return (result);
static dns_rdatalist_t *
int rdlcount = 0;
return (NULL);
rdlcount++;
rdlcount++;
return (new);
static dns_rdata_t *
int rdcount = 0;
return (NULL);
rdcount++;
rdcount++;
return (new);
static isc_uint32_t
return (when);
static isc_result_t
return (ISC_R_SUCCESS);
== ISC_R_SUCCESS);
&dataset));
return (result);
return (ISC_R_SUCCESS);
static isc_boolean_t
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);