dighost.c
来自「非常好的dns解析软件」· C语言 代码 · 共 2,368 行 · 第 1/5 页
C
2,368 行
r.base[r.length] = '\0'; strncpy(current_lookup->textname, (char*)r.base, MXNAME); isc_buffer_free(&b); nameFromString(current_lookup->textnamesigchase, &chase_name); dns_name_init(&chase_authority_name, NULL); } novalidation:#endif setup_lookup(current_lookup); do_lookup(current_lookup); } else { check_if_done(); }}/*% * If we can, clear the current lookup and start the next one running. * This calls try_clear_lookup, so may invalidate the lookup pointer. */static voidcheck_next_lookup(dig_lookup_t *lookup) { INSIST(!free_now); debug("check_next_lookup(%p)", lookup); if (ISC_LIST_HEAD(lookup->q) != NULL) { debug("still have a worker"); return; } if (try_clear_lookup(lookup)) { current_lookup = NULL; start_lookup(); }}/*% * Create and queue a new lookup as a followup to the current lookup, * based on the supplied message and section. This is used in trace and * name server search modes to start a new lookup using servers from * NS records in a reply. Returns the number of followup lookups made. */static intfollowup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section){ dig_lookup_t *lookup = NULL; dig_server_t *srv = NULL; dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_name_t *name = NULL; isc_result_t result; isc_boolean_t success = ISC_FALSE; int numLookups = 0; dns_name_t *domain; isc_boolean_t horizontal = ISC_FALSE, bad = ISC_FALSE; INSIST(!free_now); debug("following up %s", query->lookup->textname); for (result = dns_message_firstname(msg, section); result == ISC_R_SUCCESS; result = dns_message_nextname(msg, section)) { name = NULL; dns_message_currentname(msg, section, &name); if (section == DNS_SECTION_AUTHORITY) { rdataset = NULL; result = dns_message_findtype(name, dns_rdatatype_soa, 0, &rdataset); if (result == ISC_R_SUCCESS) return (0); } rdataset = NULL; result = dns_message_findtype(name, dns_rdatatype_ns, 0, &rdataset); if (result != ISC_R_SUCCESS) continue; debug("found NS set"); if (query->lookup->trace && !query->lookup->trace_root) { dns_namereln_t namereln; unsigned int nlabels; int order; domain = dns_fixedname_name(&query->lookup->fdomain); namereln = dns_name_fullcompare(name, domain, &order, &nlabels); if (namereln == dns_namereln_equal) { if (!horizontal) printf(";; BAD (HORIZONTAL) REFERRAL\n"); horizontal = ISC_TRUE; } else if (namereln != dns_namereln_subdomain) { if (!bad) printf(";; BAD REFERRAL\n"); bad = ISC_TRUE; continue; } } for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { char namestr[DNS_NAME_FORMATSIZE]; dns_rdata_ns_t ns; if (query->lookup->trace_root && query->lookup->nsfound >= MXSERV) break; dns_rdataset_current(rdataset, &rdata); query->lookup->nsfound++; (void)dns_rdata_tostruct(&rdata, &ns, NULL); dns_name_format(&ns.name, namestr, sizeof(namestr)); dns_rdata_freestruct(&ns); /* Initialize lookup if we've not yet */ debug("found NS %d %s", numLookups, namestr); numLookups++; if (!success) { success = ISC_TRUE; lookup_counter++; lookup = requeue_lookup(query->lookup, ISC_FALSE); cancel_lookup(query->lookup); lookup->doing_xfr = ISC_FALSE; if (!lookup->trace_root && section == DNS_SECTION_ANSWER) lookup->trace = ISC_FALSE; else lookup->trace = query->lookup->trace; lookup->ns_search_only = query->lookup->ns_search_only; lookup->trace_root = ISC_FALSE; if (lookup->ns_search_only) lookup->recurse = ISC_FALSE; dns_fixedname_init(&lookup->fdomain); domain = dns_fixedname_name(&lookup->fdomain); dns_name_copy(name, domain, NULL); } srv = make_server(namestr, namestr); debug("adding server %s", srv->servername); ISC_LIST_APPEND(lookup->my_server_list, srv, link); dns_rdata_reset(&rdata); } } if (lookup == NULL && section == DNS_SECTION_ANSWER && (query->lookup->trace || query->lookup->ns_search_only)) return (followup_lookup(msg, query, DNS_SECTION_AUTHORITY)); /* * Randomize the order the nameserver will be tried. */ if (numLookups > 1) { isc_uint32_t i, j; dig_serverlist_t my_server_list; ISC_LIST_INIT(my_server_list); for (i = numLookups; i > 0; i--) { isc_random_get(&j); j %= i; srv = ISC_LIST_HEAD(lookup->my_server_list); while (j-- > 0) srv = ISC_LIST_NEXT(srv, link); ISC_LIST_DEQUEUE(lookup->my_server_list, srv, link); ISC_LIST_APPEND(my_server_list, srv, link); } ISC_LIST_APPENDLIST(lookup->my_server_list, my_server_list, link); } return (numLookups);}/*% * Create and queue a new lookup using the next origin from the search * list, read in setup_system(). * * Return ISC_TRUE iff there was another searchlist entry. */static isc_boolean_tnext_origin(dns_message_t *msg, dig_query_t *query) { dig_lookup_t *lookup; dig_searchlist_t *search; UNUSED(msg); INSIST(!free_now); debug("next_origin()"); debug("following up %s", query->lookup->textname); if (!usesearch) /* * We're not using a search list, so don't even think * about finding the next entry. */ return (ISC_FALSE); if (query->lookup->origin == NULL && !query->lookup->need_search) /* * Then we just did rootorg; there's nothing left. */ return (ISC_FALSE); if (query->lookup->origin == NULL && query->lookup->need_search) { lookup = requeue_lookup(query->lookup, ISC_TRUE); lookup->origin = ISC_LIST_HEAD(search_list); lookup->need_search = ISC_FALSE; } else { search = ISC_LIST_NEXT(query->lookup->origin, link); if (search == NULL && query->lookup->done_as_is) return (ISC_FALSE); lookup = requeue_lookup(query->lookup, ISC_TRUE); lookup->origin = search; } cancel_lookup(query->lookup); return (ISC_TRUE);}/*% * Insert an SOA record into the sendmessage in a lookup. Used for * creating IXFR queries. */static voidinsert_soa(dig_lookup_t *lookup) { isc_result_t result; dns_rdata_soa_t soa; dns_rdata_t *rdata = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdataset_t *rdataset = NULL; dns_name_t *soaname = NULL; debug("insert_soa()"); soa.mctx = mctx; soa.serial = lookup->ixfr_serial; soa.refresh = 0; soa.retry = 0; soa.expire = 0; soa.minimum = 0; soa.common.rdclass = lookup->rdclass; soa.common.rdtype = dns_rdatatype_soa; dns_name_init(&soa.origin, NULL); dns_name_init(&soa.contact, NULL); dns_name_clone(dns_rootname, &soa.origin); dns_name_clone(dns_rootname, &soa.contact); isc_buffer_init(&lookup->rdatabuf, lookup->rdatastore, sizeof(lookup->rdatastore)); result = dns_message_gettemprdata(lookup->sendmsg, &rdata); check_result(result, "dns_message_gettemprdata"); result = dns_rdata_fromstruct(rdata, lookup->rdclass, dns_rdatatype_soa, &soa, &lookup->rdatabuf); check_result(result, "isc_rdata_fromstruct"); result = dns_message_gettemprdatalist(lookup->sendmsg, &rdatalist); check_result(result, "dns_message_gettemprdatalist"); result = dns_message_gettemprdataset(lookup->sendmsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdatalist_init(rdatalist); rdatalist->type = dns_rdatatype_soa; rdatalist->rdclass = lookup->rdclass; rdatalist->covers = 0; rdatalist->ttl = 0; ISC_LIST_INIT(rdatalist->rdata); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); dns_rdataset_init(rdataset); dns_rdatalist_tordataset(rdatalist, rdataset); result = dns_message_gettempname(lookup->sendmsg, &soaname); check_result(result, "dns_message_gettempname"); dns_name_init(soaname, NULL); dns_name_clone(lookup->name, soaname); ISC_LIST_INIT(soaname->list); ISC_LIST_APPEND(soaname->list, rdataset, link); dns_message_addname(lookup->sendmsg, soaname, DNS_SECTION_AUTHORITY);}/*% * Setup the supplied lookup structure, making it ready to start sending * queries to servers. Create and initialize the message to be sent as * well as the query structures and buffer space for the replies. If the * server list is empty, clone it from the system default list. */voidsetup_lookup(dig_lookup_t *lookup) { isc_result_t result; isc_uint32_t id; int len; dig_server_t *serv; dig_query_t *query; isc_buffer_t b; dns_compress_t cctx; char store[MXNAME];#ifdef WITH_IDN idn_result_t mr; char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME];#endif#ifdef WITH_IDN result = dns_name_settotextfilter(output_filter); check_result(result, "dns_name_settotextfilter");#endif REQUIRE(lookup != NULL); INSIST(!free_now); debug("setup_lookup(%p)", lookup); result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &lookup->sendmsg); check_result(result, "dns_message_create"); if (lookup->new_search) { debug("resetting lookup counter."); lookup_counter = 0; } if (ISC_LIST_EMPTY(lookup->my_server_list)) { debug("cloning server list"); clone_server_list(server_list, &lookup->my_server_list); } result = dns_message_gettempname(lookup->sendmsg, &lookup->name); check_result(result, "dns_message_gettempname"); dns_name_init(lookup->name, NULL); isc_buffer_init(&lookup->namebuf, lookup->namespace, sizeof(lookup->namespace)); isc_buffer_init(&lookup->onamebuf, lookup->onamespace, sizeof(lookup->onamespace));#ifdef WITH_IDN /* * We cannot convert `textname' and `origin' separately. * `textname' doesn't contain TLD, but local mapping needs * TLD. */ mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname, utf8_textname, sizeof(utf8_textname)); idn_check_result(mr, "convert textname to UTF-8");#endif /* * If the name has too many dots, force the origin to be NULL * (which produces an absolute lookup). Otherwise, take the origin * we have if there's one in the struct already. If it's NULL, * take the first entry in the searchlist iff either usesearch * is TRUE or we got a domain line in the resolv.conf file. */ if (lookup->new_search) {#ifdef WITH_IDN if ((count_dots(utf8_textname) >= ndots) || !usesearch) { lookup->origin = NULL; /* Force abs lookup */ lookup->done_as_is = ISC_TRUE; lookup->need_search = usesearch; } else if (lookup->origin == NULL && usesearch) { lookup->origin = ISC_LIST_HEAD(search_list); lookup->need_search = ISC_FALSE; }#else if ((count_dots(lookup->textname) >= ndots) || !usesearch) { lookup->origin = NULL; /* Force abs lookup */ lookup->done_as_is = ISC_TRUE; lookup->need_search = usesearch; } else if (lookup->origin == NULL && usesearch) { lookup->origin = ISC_LIST_HEAD(search_list); lookup->need_search = ISC_FALSE; }#endif }#ifdef WITH_IDN if (lookup->origin != NULL) { mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->origin->origin, utf8_origin, sizeof(utf8_origin)); idn_check_result(mr, "convert origin to UTF-8"); mr = append_textname(utf8_textname, utf8_origin, sizeof(utf8_textname)); idn_check_result(mr, "append origin to textname"); } mr = idn_encodename(IDN_LOCALMAP | IDN_NAMEPREP | IDN_ASCCHECK | IDN_IDNCONV | IDN_LENCHECK, utf8_textname, idn_textname, sizeof(idn_textname)); idn_check_result(mr, "convert UTF-8 textname to IDN encoding");#else if (lookup->origin != NULL) { debug("trying origin %s", lookup->origin->origin); result = dns_message_gettempname(lookup->sendmsg, &lookup->oname); check_result(result, "dns_message_gettempname"); dns_name_init(lookup->oname, NULL); /* XXX Helper funct to conv char* to name? */ len = strlen(lookup->origin->origin); isc_buffer_init(&b, lookup->origin->origin, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->oname, &b, dns_rootname, ISC_FALSE, &lookup->onamebuf); if (result != ISC_R_SUCCESS) { dns_message_puttempname(lookup->sendmsg, &lookup->name); dns_message_puttempname(lookup->sendmsg, &lookup->oname); fatal("'%s' is not in legal name syntax (%s)", lookup->origin->origin, isc_result_totext(result)); } if (lookup->trace && lookup->trace_root) { dns_name_clone(dns_rootname, lookup->name); } else { len = strlen(lookup->textname); isc_buffer_init(&b, lookup->textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->name, &b, lookup->oname, ISC_FALSE, &lookup->namebuf); } if (result != ISC_R_SUCCESS) { dns_message_puttempname(lookup->sendmsg, &lookup->name); dns_message_puttempname(lookup->sendmsg, &lookup->oname); fatal("'%s' is not in legal name syntax (%s)", lookup->textname, isc_result_totext(result)); } dns_message_puttempname(lookup->sendmsg, &lookup->oname); } else#endif { debug("using root origin"); if (lookup->trace && lookup->trace_root) dns_name_clone(dns_rootname, lookup->name); else {#ifdef WITH_IDN len = strlen(idn_textname); isc_buffer_init(&b, idn_textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->name, &b, dns_rootname, ISC_FALSE, &lookup->namebuf);#else len = strlen(lookup->textname); isc_buffer_init(&b, lookup->textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->name, &b, dns_rootname, ISC_FALSE, &lookup->namebuf);#endif } if (result != ISC_R_SUCCESS) { dns_message_puttempname(lookup->sendmsg, &lookup->name); isc_buffer_init(&b, store, MXNAME); fatal("'%s' is not a legal name " "(%s)", lookup->textname, isc_result_totext(result)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?