📄 dighost.c
字号:
lwresult = add_nameserver(lwconf, "::1", AF_INET6); if (lwresult != ISC_R_SUCCESS) fatal("add_nameserver failed"); } } if (ISC_LIST_EMPTY(server_list)) copy_server_list(lwconf, &server_list); if (keyfile[0] != 0) setup_file_key(); else if (keysecret[0] != 0) setup_text_key();#ifdef DIG_SIGCHASE /* Setup the list of messages for +sigchase */ ISC_LIST_INIT(chase_message_list); ISC_LIST_INIT(chase_message_list2); dns_name_init(&chase_name, NULL);#if DIG_SIGCHASE_TD dns_name_init(&chase_current_name, NULL); dns_name_init(&chase_authority_name, NULL);#endif#if DIG_SIGCHASE_BU dns_name_init(&chase_signame, NULL);#endif#endif}static voidclear_searchlist(void) { dig_searchlist_t *search; while ((search = ISC_LIST_HEAD(search_list)) != NULL) { ISC_LIST_UNLINK(search_list, search, link); isc_mem_free(mctx, search); }}/* * Override the search list derived from resolv.conf by 'domain'. */voidset_search_domain(char *domain) { dig_searchlist_t *search; clear_searchlist(); search = make_searchlist_entry(domain); ISC_LIST_APPEND(search_list, search, link);}/* * Setup the ISC and DNS libraries for use by the system. */voidsetup_libs(void) { isc_result_t result; debug("setup_libs()"); result = isc_net_probeipv4(); if (result == ISC_R_SUCCESS) have_ipv4 = ISC_TRUE; result = isc_net_probeipv6(); if (result == ISC_R_SUCCESS) have_ipv6 = ISC_TRUE; if (!have_ipv6 && !have_ipv4) fatal("can't find either v4 or v6 networking"); result = isc_mem_create(0, 0, &mctx); check_result(result, "isc_mem_create"); result = isc_taskmgr_create(mctx, 1, 0, &taskmgr); check_result(result, "isc_taskmgr_create"); result = isc_task_create(taskmgr, 0, &global_task); check_result(result, "isc_task_create"); result = isc_timermgr_create(mctx, &timermgr); check_result(result, "isc_timermgr_create"); result = isc_socketmgr_create(mctx, &socketmgr); check_result(result, "isc_socketmgr_create"); result = isc_entropy_create(mctx, &entp); check_result(result, "isc_entropy_create"); result = dst_lib_init(mctx, entp, 0); check_result(result, "dst_lib_init"); is_dst_up = ISC_TRUE; result = isc_mempool_create(mctx, COMMSIZE, &commctx); check_result(result, "isc_mempool_create"); isc_mempool_setname(commctx, "COMMPOOL"); /* * 6 and 2 set as reasonable parameters for 3 or 4 nameserver * systems. */ isc_mempool_setfreemax(commctx, 6); isc_mempool_setfillcount(commctx, 2); result = isc_mutex_init(&lookup_lock); check_result(result, "isc_mutex_init"); dns_result_register();}/* * Add EDNS0 option record to a message. Currently, the only supported * options are UDP buffer size and the DO bit. */static voidadd_opt(dns_message_t *msg, isc_uint16_t udpsize, isc_boolean_t dnssec) { dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdata_t *rdata = NULL; isc_result_t result; debug("add_opt()"); result = dns_message_gettemprdataset(msg, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdataset_init(rdataset); result = dns_message_gettemprdatalist(msg, &rdatalist); check_result(result, "dns_message_gettemprdatalist"); result = dns_message_gettemprdata(msg, &rdata); check_result(result, "dns_message_gettemprdata"); debug("setting udp size of %d", udpsize); rdatalist->type = dns_rdatatype_opt; rdatalist->covers = 0; rdatalist->rdclass = udpsize; rdatalist->ttl = 0; if (dnssec) rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO; rdata->data = NULL; rdata->length = 0; ISC_LIST_INIT(rdatalist->rdata); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); dns_rdatalist_tordataset(rdatalist, rdataset); result = dns_message_setopt(msg, rdataset); check_result(result, "dns_message_setopt");}/* * Add a question section to a message, asking for the specified name, * type, and class. */static voidadd_question(dns_message_t *message, dns_name_t *name, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype){ dns_rdataset_t *rdataset; isc_result_t result; debug("add_question()"); rdataset = NULL; result = dns_message_gettemprdataset(message, &rdataset); check_result(result, "dns_message_gettemprdataset()"); dns_rdataset_init(rdataset); dns_rdataset_makequestion(rdataset, rdclass, rdtype); ISC_LIST_APPEND(name->list, rdataset, link);}/* * Check if we're done with all the queued lookups, which is true iff * all sockets, sends, and recvs are accounted for (counters == 0), * and the lookup list is empty. * If we are done, pass control back out to dighost_shutdown() (which is * part of dig.c, host.c, or nslookup.c) to either shutdown the system as * a whole or reseed the lookup list. */static voidcheck_if_done(void) { debug("check_if_done()"); debug("list %s", ISC_LIST_EMPTY(lookup_list) ? "empty" : "full"); if (ISC_LIST_EMPTY(lookup_list) && current_lookup == NULL && sendcount == 0) { INSIST(sockcount == 0); INSIST(recvcount == 0); debug("shutting down"); dighost_shutdown(); }}/* * Clear out a query when we're done with it. WARNING: This routine * WILL invalidate the query pointer. */static voidclear_query(dig_query_t *query) { dig_lookup_t *lookup; REQUIRE(query != NULL); debug("clear_query(%p)", query); lookup = query->lookup; if (lookup->current_query == query) lookup->current_query = NULL; ISC_LIST_UNLINK(lookup->q, query, link); if (ISC_LINK_LINKED(&query->recvbuf, link)) ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf, link); if (ISC_LINK_LINKED(&query->lengthbuf, link)) ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf, link); INSIST(query->recvspace != NULL); if (query->sock != NULL) { isc_socket_detach(&query->sock); sockcount--; debug("sockcount=%d", sockcount); } isc_mempool_put(commctx, query->recvspace); isc_buffer_invalidate(&query->recvbuf); isc_buffer_invalidate(&query->lengthbuf); isc_mem_free(mctx, query);}/* * Try and clear out a lookup if we're done with it. Return ISC_TRUE if * the lookup was successfully cleared. If ISC_TRUE is returned, the * lookup pointer has been invalidated. */static isc_boolean_ttry_clear_lookup(dig_lookup_t *lookup) { dig_server_t *s; dig_query_t *q; void *ptr; REQUIRE(lookup != NULL); debug("try_clear_lookup(%p)", lookup); if (ISC_LIST_HEAD(lookup->q) != NULL) { if (debugging) { q = ISC_LIST_HEAD(lookup->q); while (q != NULL) { debug("query to %s still pending", q->servname); q = ISC_LIST_NEXT(q, link); } return (ISC_FALSE); } } /* * At this point, we know there are no queries on the lookup, * so can make it go away also. */ debug("cleared"); s = ISC_LIST_HEAD(lookup->my_server_list); while (s != NULL) { debug("freeing server %p belonging to %p", s, lookup); ptr = s; s = ISC_LIST_NEXT(s, link); ISC_LIST_DEQUEUE(lookup->my_server_list, (dig_server_t *)ptr, link); isc_mem_free(mctx, ptr); } if (lookup->sendmsg != NULL) dns_message_destroy(&lookup->sendmsg); if (lookup->querysig != NULL) { debug("freeing buffer %p", lookup->querysig); isc_buffer_free(&lookup->querysig); } if (lookup->timer != NULL) isc_timer_detach(&lookup->timer); if (lookup->sendspace != NULL) isc_mempool_put(commctx, lookup->sendspace); if (lookup->tsigctx != NULL) dst_context_destroy(&lookup->tsigctx); isc_mem_free(mctx, lookup); return (ISC_TRUE);}/* * If we can, start the next lookup in the queue running. * This assumes that the lookup on the head of the queue hasn't been * started yet. It also removes the lookup from the head of the queue, * setting the current_lookup pointer pointing to it. */voidstart_lookup(void) { debug("start_lookup()"); if (cancel_now) return; /* * If there's a current lookup running, we really shouldn't get * here. */ INSIST(current_lookup == NULL); current_lookup = ISC_LIST_HEAD(lookup_list); /* * Put the current lookup somewhere so cancel_all can find it */ if (current_lookup != NULL) { ISC_LIST_DEQUEUE(lookup_list, current_lookup, link);#if DIG_SIGCHASE_TD if (current_lookup->do_topdown && !current_lookup->rdtype_sigchaseset) { dst_key_t * trustedkey = NULL; isc_buffer_t *b = NULL; isc_region_t r; isc_result_t result; dns_name_t query_name; dns_name_t * key_name; int i; result = get_trusted_key(mctx); if (result != ISC_R_SUCCESS) { printf("\n;; No trusted key, " "+sigchase option is disabled\n"); current_lookup->sigchase = ISC_FALSE; goto novalidation; } dns_name_init(&query_name, NULL); nameFromString(current_lookup->textname, &query_name); for (i = 0; i< tk_list.nb_tk; i++) { key_name = dst_key_name(tk_list.key[i]); if (dns_name_issubdomain(&query_name, key_name) == ISC_TRUE) trustedkey = tk_list.key[i]; /* * Verifier que la temp est bien la plus basse * WARNING */ } if (trustedkey == NULL) { printf("\n;; The queried zone: "); dns_name_print(&query_name, stdout); printf(" isn't a subdomain of any Trusted Keys" ": +sigchase option is disable\n"); current_lookup->sigchase = ISC_FALSE; dns_name_free(&query_name, mctx); goto novalidation; } dns_name_free(&query_name, mctx); current_lookup->rdtype_sigchase = current_lookup->rdtype; current_lookup->rdtype_sigchaseset = current_lookup->rdtypeset; current_lookup->rdtype = dns_rdatatype_ns; current_lookup->qrdtype_sigchase = current_lookup->qrdtype; current_lookup->qrdtype = dns_rdatatype_ns; current_lookup->rdclass_sigchase = current_lookup->rdclass; current_lookup->rdclass_sigchaseset = current_lookup->rdclassset; current_lookup->rdclass = dns_rdataclass_in; strncpy(current_lookup->textnamesigchase, current_lookup->textname, MXNAME); current_lookup->trace_root_sigchase = ISC_TRUE; result = isc_buffer_allocate(mctx, &b, BUFSIZE); check_result(result, "isc_buffer_allocate"); result = dns_name_totext(dst_key_name(trustedkey), ISC_FALSE, b); check_result(result, "dns_name_totext"); isc_buffer_usedregion(b, &r); 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; 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); rdataset = NULL; result = dns_message_findtype(name, dns_rdatatype_ns, 0, &rdataset); if (result != ISC_R_SUCCESS) continue; debug("found NS set"); 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++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -