📄 master.c
字号:
isc_boolean_t finish_origin = ISC_FALSE; isc_boolean_t finish_include = ISC_FALSE; isc_boolean_t read_till_eol = ISC_FALSE; isc_boolean_t initialws; char *include_file = NULL; isc_token_t token; isc_result_t result = ISC_R_UNEXPECTED; 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_ft; 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; int target_size = TSIZ; int new_in_use; unsigned int loop_cnt = 0; isc_mem_t *mctx; dns_rdatacallbacks_t *callbacks; dns_incctx_t *ictx; char *range = NULL; char *lhs = NULL; char *gtype = NULL; char *rhs = NULL; const char *source = ""; unsigned long line = 0; isc_boolean_t explicit_ttl; isc_stdtime_t now; char classname1[DNS_RDATACLASS_FORMATSIZE]; char classname2[DNS_RDATACLASS_FORMATSIZE]; unsigned int options = 0; REQUIRE(DNS_LCTX_VALID(lctx)); callbacks = lctx->callbacks; mctx = lctx->mctx; ictx = lctx->inc; ISC_LIST_INIT(glue_list); ISC_LIST_INIT(current_list); isc_stdtime_get(&now); /* * Allocate target_size of buffer space. This is greater than twice * the maximum individual RR data size. */ target_mem = isc_mem_get(mctx, target_size); if (target_mem == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } isc_buffer_init(&target, target_mem, target_size); target_save = target; if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) options |= DNS_RDATA_CHECKNAMES; if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) options |= DNS_RDATA_CHECKNAMESFAIL; if ((lctx->options & DNS_MASTER_CHECKMX) != 0) options |= DNS_RDATA_CHECKMX; if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0) options |= DNS_RDATA_CHECKMXFAIL; source = isc_lex_getsourcename(lctx->lex); do { initialws = ISC_FALSE; line = isc_lex_getsourceline(lctx->lex); GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING, &token, ISC_TRUE); line = isc_lex_getsourceline(lctx->lex); if (token.type == isc_tokentype_eof) { if (read_till_eol) WARNUNEXPECTEDEOF(lctx->lex); /* Pop the include stack? */ if (ictx->parent != NULL) { COMMITALL; lctx->inc = ictx->parent; ictx->parent = NULL; incctx_destroy(lctx->mctx, ictx); RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); ictx = lctx->inc; EXPECTEOL; continue; } done = ISC_TRUE; continue; } if (token.type == isc_tokentype_eol) { read_till_eol = ISC_FALSE; continue; /* blank line */ } if (read_till_eol) continue; if (token.type == isc_tokentype_initialws) { /* * Still working on the same name. */ initialws = ISC_TRUE; } else if (token.type == isc_tokentype_string || token.type == isc_tokentype_qstring) { /* * "$" Support. * * "$ORIGIN" and "$INCLUDE" can both take domain names. * The processing of "$ORIGIN" and "$INCLUDE" extends * across the normal domain name processing. */ if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); finish_origin = ISC_TRUE; } else if (strcasecmp(DNS_AS_STR(token), "$TTL") == 0) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); result = dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; limit_ttl(callbacks, source, line, &lctx->ttl); lctx->default_ttl = lctx->ttl; lctx->default_ttl_known = ISC_TRUE; EXPECTEOL; continue; } else if (strcasecmp(DNS_AS_STR(token), "$INCLUDE") == 0) { COMMITALL; if ((lctx->options & DNS_MASTER_NOINCLUDE) != 0) { (callbacks->error)(callbacks, "%s: %s:%lu: $INCLUDE not allowed", "dns_master_load", source, line); result = DNS_R_REFUSED; goto insist_and_cleanup; } if (ttl_offset != 0) { (callbacks->error)(callbacks, "%s: %s:%lu: $INCLUDE " "may not be used with $DATE", "dns_master_load", source, line); result = DNS_R_SYNTAX; goto insist_and_cleanup; } GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token, ISC_FALSE); if (include_file != NULL) isc_mem_free(mctx, include_file); include_file = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (include_file == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); if (token.type == isc_tokentype_eol || token.type == isc_tokentype_eof) { if (token.type == isc_tokentype_eof) WARNUNEXPECTEDEOF(lctx->lex); isc_lex_ungettoken(lctx->lex, &token); /* * No origin field. */ result = pushfile(include_file, ictx->origin, lctx); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGITFILE(result, include_file); continue; } else if (result != ISC_R_SUCCESS) { LOGITFILE(result, include_file); goto insist_and_cleanup; } ictx = lctx->inc; line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); continue; } /* * There is an origin field. Fall through * to domain name processing code and do * the actual inclusion later. */ finish_include = ISC_TRUE; } else if (strcasecmp(DNS_AS_STR(token), "$DATE") == 0) { isc_int64_t dump_time64; isc_stdtime_t dump_time, current_time; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); isc_stdtime_get(¤t_time); result = dns_time64_fromtext(DNS_AS_STR(token), &dump_time64); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); dump_time64 = 0; } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; dump_time = (isc_stdtime_t)dump_time64; if (dump_time != dump_time64) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %s:%lu: $DATE outside epoch", "dns_master_load", source, line); result = ISC_R_UNEXPECTED; goto insist_and_cleanup; } if (dump_time > current_time) { UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %s:%lu: " "$DATE in future, using current date", "dns_master_load", source, line); dump_time = current_time; } ttl_offset = current_time - dump_time; EXPECTEOL; continue; } else if (strcasecmp(DNS_AS_STR(token), "$GENERATE") == 0) { /* * 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 = lhs = gtype = rhs = NULL; /* RANGE */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); range = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (range == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } /* LHS */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); lhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (lhs == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } rdclass = 0; explicit_ttl = ISC_FALSE; /* CLASS? */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) { GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } /* TTL? */ if (dns_ttl_fromtext(&token.value.as_textregion, &lctx->ttl) == ISC_R_SUCCESS) { limit_ttl(callbacks, source, line, &lctx->ttl); lctx->ttl_known = ISC_TRUE; explicit_ttl = ISC_TRUE; GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); } /* CLASS? */ if (rdclass == 0 && dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == ISC_R_SUCCESS) GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); /* TYPE */ gtype = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (gtype == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } /* RHS */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); rhs = isc_mem_strdup(mctx, DNS_AS_STR(token)); if (rhs == NULL) { result = ISC_R_NOMEMORY; goto log_and_cleanup; } if (!lctx->ttl_known && !lctx->default_ttl_known) { (*callbacks->error)(callbacks, "%s: %s:%lu: no TTL specified", "dns_master_load", source, line); result = DNS_R_NOTTL; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); lctx->ttl = 0; } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } else if (!explicit_ttl && lctx->default_ttl_known) { lctx->ttl = lctx->default_ttl; } /* * If the class specified does not match the * zone's class print out a error message and * exit. */ if (rdclass != 0 && rdclass != lctx->zclass) { goto bad_class; } result = generate(lctx, range, lhs, gtype, rhs, source, line); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; EXPECTEOL; continue; } else if (strncasecmp(DNS_AS_STR(token), "$", 1) == 0) { (callbacks->error)(callbacks, "%s: %s:%lu: " "unknown $ directive '%s'", "dns_master_load", source, line, DNS_AS_STR(token)); result = DNS_R_SYNTAX; if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; } /* * Normal processing resumes. * * Find a free name buffer. */ for (new_in_use = 0; new_in_use < NBUFS; new_in_use++) if (!ictx->in_use[new_in_use]) break; INSIST(new_in_use < NBUFS); dns_fixedname_init(&ictx->fixed[new_in_use]); new_name = dns_fixedname_name(&ictx->fixed[new_in_use]); isc_buffer_init(&buffer, token.value.as_region.base, token.value.as_region.length); isc_buffer_add(&buffer, token.value.as_region.length); isc_buffer_setactive(&buffer, token.value.as_region.length); result = dns_name_fromtext(new_name, &buffer, ictx->origin, ISC_FALSE, NULL); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGIT(result); read_till_eol = ISC_TRUE; continue; } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; /* * Finish $ORIGIN / $INCLUDE processing if required. */ if (finish_origin) { if (ictx->origin_in_use != -1) ictx->in_use[ictx->origin_in_use] = ISC_FALSE; ictx->origin_in_use = new_in_use; ictx->in_use[ictx->origin_in_use] = ISC_TRUE; ictx->origin = new_name; finish_origin = ISC_FALSE; EXPECTEOL; continue; } if (finish_include) { finish_include = ISC_FALSE; result = pushfile(include_file, new_name, lctx); if (MANYERRS(lctx, result)) { SETRESULT(lctx, result); LOGITFILE(result, include_file); continue; } else if (result != ISC_R_SUCCESS) { LOGITFILE(result, include_file); goto insist_and_cleanup; } ictx = lctx->inc; line = isc_lex_getsourceline(lctx->lex); source = isc_lex_getsourcename(lctx->lex); 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(). */ if (ictx->glue != NULL && dns_name_compare(ictx->glue, new_name) != 0) { 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 (ictx->glue_in_use != -1) ictx->in_use[ictx->glue_in_use] = ISC_FALSE; ictx->glue_in_use = -1; ictx->glue = NULL; rdcount = rdcount_save; rdlcount = rdlcount_save; target = target_save; } /* * 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 ((ictx->glue == NULL) && (ictx->current == NULL || dns_name_compare(ictx->current, new_name) != 0)) { if (current_has_delegation && is_glue(¤t_list, new_name)) { rdcount_save = rdcount; rdlcount_save = rdlcount; target_save = target; ictx->glue = new_name; ictx->glue_in_use = new_in_use; ictx->in_use[ictx->glue_in_use] = ISC_TRUE; } else { 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; rdcount = 0; rdlcount = 0; if (ictx->current_in_use != -1) ictx->in_use[ictx->current_in_use] = ISC_FALSE; ictx->current_in_use = new_in_use; ictx->in_use[ictx->current_in_use] = ISC_TRUE; ictx->current = new_name; current_has_delegation = ISC_FALSE; isc_buffer_init(&target, target_mem, target_size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -