📄 resolve.c
字号:
return (rv);}/*--- process_rr() ------------------------------------------------------------------------------*//************************************************************************************************** ADD_AUTHORITY_NS Adds AUTHORITY records for any NS records that match the request.**************************************************************************************************/static inline voidadd_authority_ns(TASK *t, datasection_t section, MYDNS_SOA *soa, char *match_label){ if (!t->ns.size && section == ANSWER) { register MYDNS_RR *rr = NULL, *r = NULL; register char *label = NULL;#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: add_authority_ns(%s, (%s), \"%s\")", desctask(t), resolve_datasection_str[section], soa->origin, match_label);#endif /* Match down label by label in `label' -- include first matching NS record(s) */ for (label = match_label; *label; label++) { if (label == match_label || *label == '.') { if (label[0] == '.' && label[1]) label++; /* Advance past leading dot */ /* Ignore NS records on wildcard (is that correct behavior?) */ if (*label != '*') {#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: Checking for NS (AUTHORITY) for label \"%s\" (would be glue)", desctask(t), label);#endif if ((rr = find_rr(t, soa, DNS_QTYPE_NS, label))) { for (r = rr; r; r = r->next) { char name[DNS_MAXNAMELEN+1]; snprintf(name, sizeof(name), "%s.%s", label, soa->origin); rrlist_add(t, AUTHORITY, DNS_RRTYPE_RR, (void *)r, name); } t->sort_level++; mydns_rr_free(rr);#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: FOUND GLUE", desctask(t));#endif return; } } } } /* Nothing added - try empty label */#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: Checking for NS (AUTHORITY) for empty label", desctask(t));#endif if ((rr = find_rr(t, soa, DNS_QTYPE_NS, label))) { for (r = rr; r; r = r->next) rrlist_add(t, AUTHORITY, DNS_RRTYPE_RR, (void *)r, soa->origin); t->sort_level++; mydns_rr_free(rr); } }}/*--- add_authority_ns() ------------------------------------------------------------------------*//************************************************************************************************** RESOLVE_LABEL Examine `label' (or a wildcard). Add any relevant records. Returns nonzero if resolution is complete (because matches were found), else 0.**************************************************************************************************/static intresolve_label(TASK *t, datasection_t section, dns_qtype_t qtype, char *fqdn, MYDNS_SOA *soa, char *label, int full_match, int level){ register MYDNS_RR *rr = NULL; register int rv = 0;#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: resolve_label(%s, %s, \"%s\", (%s), \"%s\", %d, %d)", desctask(t), resolve_datasection_str[section], mydns_qtype_str(qtype), fqdn, soa->origin, label, full_match, level);#endif /* Do any records match this label exactly? */ /* Only check this if the label is the first in the list */ if (full_match) { if ((rr = find_rr(t, soa, DNS_QTYPE_ANY, label))) { rv = process_rr(t, section, qtype, fqdn, soa, label, rr, level); mydns_rr_free(rr); add_authority_ns(t, section, soa, label); return (rv); } } /* No exact match. If `label' isn't empty, replace the first part of the label with `*' and check for wildcard matches. */ if (*label && !rv) { char wclabel[DNS_MAXNAMELEN+1], *c; /* Generate wildcarded label, i.e. `*.example' or maybe just `*'. */ if (!(c = strchr(label, '.'))) wclabel[0] = '*', wclabel[1] = '\0'; else wclabel[0] = '*', strncpy(wclabel+1, c, sizeof(wclabel)-2); if ((rr = find_rr(t, soa, DNS_QTYPE_ANY, wclabel))) { rv = process_rr(t, section, qtype, fqdn, soa, wclabel, rr, level); mydns_rr_free(rr); add_authority_ns(t, section, soa, wclabel); return (rv); } } /* STILL no match - check for NS records for child delegation */ if (*label && !rv && (rr = find_rr(t, soa, DNS_QTYPE_NS, label))) { rv = process_rr(t, section, qtype, fqdn, soa, label, rr, level); mydns_rr_free(rr); add_authority_ns(t, section, soa, label); return (rv); } return (rv);}/*--- resolve_label() ---------------------------------------------------------------------------*//************************************************************************************************** RESOLVE Resolves the specified name, storing all data found in the specified section. If `section' is ANSWER, this function will set an error if we lack an authoritative answer. Returns number of records inserted, or -1 if an error occurred.**************************************************************************************************/intresolve(TASK *t, datasection_t section, dns_qtype_t qtype, char *fqdn, int level){ char name[DNS_MAXNAMELEN+1]; register MYDNS_SOA *soa; register int rv = 0; register char *label;#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: resolve(%s, %s, \"%s\", %d)", desctask(t), resolve_datasection_str[section], mydns_qtype_str(qtype), fqdn, level);#endif#if STATUS_ENABLED if (t->qclass == DNS_CLASS_CHAOS) return remote_status(t);#endif if (!axfr_enabled && t->qtype == DNS_QTYPE_AXFR) return dnserror(t, DNS_RCODE_REFUSED, ERR_NO_AXFR); /* Is the request for a SOA record only? */ if (t->qtype == DNS_QTYPE_SOA && section == ANSWER) return resolve_soa(t, section, fqdn); /* Load SOA record for this name - if section is ANSWER and no SOA is found, we're not authoritative */#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: Look up soa record for this zone", desctask(t));#endif memset(name, 0, sizeof(name)); if (!(soa = find_soa(t, fqdn, name))) { if ((section == ANSWER) && !level) { if (forward_recursive && t->hdr.rd) return recursive_fwd(t); else return dnserror(t, DNS_RCODE_REFUSED, ERR_ZONE_NOT_FOUND); } return 0; } t->zone = soa->id; t->minimum_ttl = soa->minimum; /* We are authoritative; Set `aa' flag */ if (section == ANSWER) {#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: We are authoritative, zone_id is %u", desctask(t), soa->id);#endif t->hdr.aa = 1; } /* If the request is ANY, and `fqdn' exactly matches the origin, include SOA */ if ((qtype == DNS_QTYPE_ANY) && (section == ANSWER) && !strcasecmp(fqdn, soa->origin)) { rrlist_add(t, section, DNS_RRTYPE_SOA, (void *)soa, soa->origin); t->sort_level++; } /* Examine each label in the name, one at a time; look for relevant records */#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: Examining \"%s\", label by label", desctask(t), name);#endif for (label = name; ; label++) { if (label == name || *label == '.') { if (label[0] == '.' && label[1]) label++; /* Advance past leading dot */ /* Resolve the label; if we find records, we're done. */ if ((rv = resolve_label(t, section, qtype, fqdn, soa, label, label == name, level)) != 0) break; } if (!*label) break; }#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("%s: Done examining \"%s\", label by label", desctask(t), name);#endif /* If we got this far and there are NO records, set result and send the SOA */ if (!level && !t->an.size && !t->ns.size && !t->ar.size) {#if DEBUG_ENABLED && DEBUG_RESOLVE Debug("- We are authoritative, but no RRs matched; sending %s with SOA in AUTHORITY section", t->name_ok == 1 ? "NOERROR" : "NXDOMAIN");#endif if (t->name_ok) { t->hdr.rcode = DNS_RCODE_NOERROR; t->reason = ERR_NONE; } else { t->hdr.rcode = DNS_RCODE_NXDOMAIN; t->reason = ERR_NO_MATCHING_RECORDS; } rrlist_add(t, AUTHORITY, DNS_RRTYPE_SOA, (void *)soa, soa->origin); t->sort_level++; } mydns_soa_free(soa); return (rv);} /*--- resolve() ---------------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -