📄 master.c
字号:
} /* * Check for internal wildcards. */ if ((lctx->options & DNS_MASTER_CHECKWILDCARD) != 0) check_wildcard(ictx, source, line, callbacks); } if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && !dns_name_issubdomain(new_name, lctx->top)) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(new_name, namebuf, sizeof(namebuf)); /* * Ignore out-of-zone data. */ (*callbacks->warn)(callbacks, "%s:%lu: " "ignoring out-of-zone data (%s)", source, line, namebuf); ictx->drop = ISC_TRUE; } else ictx->drop = ISC_FALSE; } else { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s:%lu: isc_lex_gettoken() returned " "unexpeced token type (%d)", source, line, token.type); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); 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; GETTOKEN(lctx->lex, 0, &token, initialws); if (initialws) { if (token.type == isc_tokentype_eol) { read_till_eol = ISC_FALSE; continue; /* blank line */ } if (token.type == isc_tokentype_eof) { WARNUNEXPECTEDEOF(lctx->lex); read_till_eol = ISC_FALSE; isc_lex_ungettoken(lctx->lex, &token); continue; } if (ictx->current == NULL) { (*callbacks->error)(callbacks, "%s:%lu: no current owner name", source, line); result = DNS_R_NOOWNER; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } } if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); explicit_ttl = ISC_FALSE; if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl) == ISC_R_SUCCESS) { limit_ttl(callbacks, source, line, &lctx->ttl); explicit_ttl = ISC_TRUE; lctx->ttl_known = ISC_TRUE; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } if (token.type != isc_tokentype_string) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_lex_gettoken() returned unexpected token type"); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (rdclass == 0 && dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); if (token.type != isc_tokentype_string) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_lex_gettoken() returned unexpected token type"); result = ISC_R_UNEXPECTED; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } result = dns_rdatatype_fromtext(&type, &token.value.as_textregion); if (result != ISC_R_SUCCESS) { (*callbacks->warn)(callbacks, "%s:%lu: unknown RR type '%.*s'", source, line, token.value.as_textregion.length, token.value.as_textregion.base); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; 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. */ if (rdclass != 0 && rdclass != lctx->zclass) { bad_class: dns_rdataclass_format(rdclass, classname1, sizeof(classname1)); dns_rdataclass_format(lctx->zclass, classname2, sizeof(classname2)); (*callbacks->error)(callbacks, "%s:%lu: class '%s' != " "zone class '%s'", source, line, classname1, classname2); result = DNS_R_BADCLASS; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (type == dns_rdatatype_ns && ictx->glue == NULL) current_has_delegation = ISC_TRUE; /* * RFC1123: MD and MF are not allowed to be loaded from * master files. */ if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && (type == dns_rdatatype_md || type == dns_rdatatype_mf)) { char typename[DNS_RDATATYPE_FORMATSIZE]; result = DNS_R_OBSOLETE; dns_rdatatype_format(type, typename, sizeof(typename)); (*callbacks->error)(callbacks, "%s:%lu: %s '%s': %s", source, line, "type", typename, dns_result_totext(result)); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else goto insist_and_cleanup; } /* * 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) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdata_size += RDSZ; rdata = new_rdata; } /* * Peek at the NS record. */ if (type == dns_rdatatype_ns && lctx->zclass == dns_rdataclass_in && (lctx->options & DNS_MASTER_CHECKNS) != 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); result = check_ns(lctx, &token, source, line); isc_lex_ungettoken(lctx->lex, &token); if ((lctx->options & DNS_MASTER_FATALNS) != 0) { if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } } /* * Check owner name. */ options &= ~DNS_RDATA_CHECKREVERSE; if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) { isc_boolean_t ok; dns_name_t *name; name = (ictx->glue != NULL) ? ictx->glue : ictx->current; ok = dns_rdata_checkowner(name, lctx->zclass, type, ISC_TRUE); if (!ok) { char namebuf[DNS_NAME_FORMATSIZE]; const char *desc; dns_name_format(name, namebuf, sizeof(namebuf)); result = DNS_R_BADOWNERNAME; desc = dns_result_totext(result); if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) { (*callbacks->error)(callbacks, "%s:%lu: %s: %s", source, line, namebuf, desc); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto cleanup; } else { (*callbacks->warn)(callbacks, "%s:%lu: %s: %s", source, line, namebuf, desc); } } if (type == dns_rdatatype_ptr && (dns_name_issubdomain(name, &in_addr_arpa) || dns_name_issubdomain(name, &ip6_arpa) || dns_name_issubdomain(name, &ip6_int))) options |= DNS_RDATA_CHECKREVERSE; } /* * Read rdata contents. */ dns_rdata_init(&rdata[rdcount]); target_ft = target; result = dns_rdata_fromtext(&rdata[rdcount], lctx->zclass, type, lctx->lex, ictx->origin, options, lctx->mctx, &target, callbacks); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (ictx->drop) { target = target_ft; continue; } if (type == dns_rdatatype_soa && (lctx->options & DNS_MASTER_ZONE) != 0 && dns_name_compare(ictx->current, lctx->top) != 0) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(ictx->current, namebuf, sizeof(namebuf)); (*callbacks->error)(callbacks, "%s:%lu: SOA " "record not at top of zone (%s)", source, line, namebuf); result = DNS_R_NOTZONETOP; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); read_till_eol = ISC_TRUE; target = target_ft; continue; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } if (type == dns_rdatatype_rrsig || type == dns_rdatatype_sig) covers = dns_rdata_covers(&rdata[rdcount]); else covers = 0; if (!lctx->ttl_known && !lctx->default_ttl_known) { if (type == dns_rdatatype_soa) { (*callbacks->warn)(callbacks, "%s:%lu: no TTL specified; " "using SOA MINTTL instead", source, line); lctx->ttl = dns_soa_getminimum(&rdata[rdcount]); limit_ttl(callbacks, source, line, &lctx->ttl); lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; } else if ((lctx->options & DNS_MASTER_HINT) != 0) { /* * Zero TTL's are fine for hints. */ lctx->ttl = 0; lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; } else { (*callbacks->warn)(callbacks, "%s:%lu: no TTL specified; " "zone rejected", source, line); result = DNS_R_NOTTL; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else { goto insist_and_cleanup; } } } else if (!explicit_ttl && lctx->default_ttl_known) { lctx->ttl = lctx->default_ttl; } else if (!explicit_ttl && lctx->warn_1035) { (*callbacks->warn)(callbacks, "%s:%lu: " "using RFC1035 TTL semantics", source, line); lctx->warn_1035 = ISC_FALSE; } if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) { dns_rdata_rrsig_t sig; (void)dns_rdata_tostruct(&rdata[rdcount], &sig, NULL); if (isc_serial_lt(sig.timeexpire, now)) { (*callbacks->warn)(callbacks, "%s:%lu: " "signature has expired", source, line); lctx->warn_sigexpired = ISC_FALSE; } } if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) && lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0) { (*callbacks->warn)(callbacks, "%s:%lu: old style DNSSEC " " zone detected", source, line); lctx->warn_tcr = ISC_FALSE; } if ((lctx->options & DNS_MASTER_AGETTL) != 0) { /* * Adjust the TTL for $DATE. If the RR has already * expired, ignore it. */ if (lctx->ttl < ttl_offset) continue; lctx->ttl -= ttl_offset; } /* * Find type in rdatalist. * If it does not exist create new one and prepend to list * as this will mimimise list traversal. */ if (ictx->glue != NULL) this = ISC_LIST_HEAD(glue_list); else this = ISC_LIST_HEAD(current_list); while (this != NULL) { if (this->type == type && this->covers == covers) break; this = ISC_LIST_NEXT(this, link); } if (this == NULL) { if (rdlcount == rdatalist_size) { new_rdatalist = grow_rdatalist(rdatalist_size + RDLSZ, rdatalist, rdatalist_size, ¤t_list, &glue_list, mctx); if (new_rdatalist == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdatalist = new_rdatalist; rdatalist_size += RDLSZ; } this = &rdatalist[rdlcount++]; this->type = type; this->covers = covers; this->rdclass = lctx->zclass; this->ttl = lctx->ttl; ISC_LIST_INIT(this->rdata); if (ictx->glue != NULL) ISC_LIST_INITANDPREPEND(glue_list, this, link); else ISC_LIST_INITANDPREPEND(current_list, this, link); } else if (this->ttl != lctx->ttl) { (*callbacks->warn)(callbacks, "%s:%lu: " "TTL set to prior TTL (%lu)", source, line, this->ttl); lctx->ttl = this->ttl; } ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link); if (ictx->glue != NULL) ictx->glue_line = line; else ictx->current_line = line; rdcount++; /* * We must have at least 64k as rdlen is 16 bits. * If we don't commit everything we have so far. */ if ((target.length - target.used) < MINTSIZ) COMMITALL; next_line: ; } while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt)); /* * Commit what has not yet been committed. */ result = commit(callbacks, lctx, ¤t_list, ictx->current, source, ictx->current_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; result = commit(callbacks, lctx, &glue_list, ictx->glue, source, ictx->glue_line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (!done) { INSIST(lctx->done != NULL && lctx->task != NULL); result = DNS_R_CONTINUE; } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) { result = lctx->result; } else if (result == ISC_R_SUCCESS && lctx->seen_include) result = DNS_R_SEENINCLUDE; goto cleanup; log_and_cleanup: LOGIT(result); insist_and_cleanup: INSIST(result != ISC_R_SUCCESS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -