📄 master.c
字号:
== 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; /* * RFC 1123: 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 RFC 1035 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); cleanup: while ((this = ISC_LIST_HEAD(current_list)) != NULL) ISC_LIST_UNLINK(current_list, this, link); while ((this = ISC_LIST_HEAD(glue_list)) != NULL) 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)); if (target_mem != NULL) isc_mem_put(mctx, target_mem, target_size); if (include_file != NULL) isc_mem_free(mctx, include_file); 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); return (result);}static isc_result_tpushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { isc_result_t result; dns_incctx_t *ictx; dns_incctx_t *new = NULL; isc_region_t r; int new_in_use; REQUIRE(master_file != NULL); REQUIRE(DNS_LCTX_VALID(lctx)); ictx = lctx->inc; lctx->seen_include = ISC_TRUE; result = incctx_create(lctx->mctx, origin, &new); if (result != ISC_R_SUCCESS) return (result); /* Set current domain. */ if (ictx->glue != NULL || ictx->current != NULL) { for (new_in_use = 0; new_in_use < NBUFS; new_in_use++) if (!new->in_use[new_in_use]) break; INSIST(new_in_use < NBUFS); new->current_in_use = new_in_use; new->current = dns_fixedname_name(&new->fixed[new->current_in_use]); new->in_use[new->current_in_use] = ISC_TRUE; dns_name_toregion((ictx->glue != NULL) ? ictx->glue : ictx->current, &r); dns_name_fromregion(new->current, &r); new->drop = ictx->drop; } result = isc_lex_openfile(lctx->lex, master_file); if (result != ISC_R_SUCCESS) goto cleanup; new->parent = ictx; lctx->inc = new; return (ISC_R_SUCCESS); cleanup: if (new != NULL) incctx_destroy(lctx->mctx, new); return (result);}isc_result_tdns_master_loadfile(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx){ dns_loadctx_t *lctx = NULL; isc_result_t result; result = loadctx_create(mctx, options, top, zclass, origin,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -