📄 dighost.c
字号:
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; } srv = make_server(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)); 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; 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) /* * Then we just did rootorg; there's nothing left. */ return (ISC_FALSE); lookup = requeue_lookup(query->lookup, ISC_TRUE); lookup->origin = ISC_LIST_NEXT(query->lookup->origin, link); 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]; 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)); /* * 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. */ /* XXX New search here? */ if ((count_dots(lookup->textname) >= ndots) || !usesearch) lookup->origin = NULL; /* Force abs lookup */ else if (lookup->origin == NULL && lookup->new_search && usesearch) { lookup->origin = ISC_LIST_HEAD(search_list); } 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 { debug("using root origin"); 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, dns_rootname, ISC_FALSE, &lookup->namebuf); } 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)); } } dns_name_format(lookup->name, store, sizeof(store)); trying(store, lookup); INSIST(dns_name_isabsolute(lookup->name)); isc_random_get(&id); lookup->sendmsg->id = (unsigned short)id & 0xFFFF; lookup->sendmsg->opcode = dns_opcode_query; lookup->msgcounter = 0; /* * If this is a trace request, completely disallow recursion, since * it's meaningless for traces. */ if (lookup->trace || (lookup->ns_search_only && !lookup->trace_root)) lookup->recurse = ISC_FALSE; if (lookup->recurse && lookup->rdtype != dns_rdatatype_axfr && lookup->rdtype != dns_rdatatype_ixfr) { debug("recursive query"); lookup->sendmsg->flags |= DNS_MESSAGEFLAG_RD; } /* XXX aaflag */ if (lookup->aaonly) { debug("AA query"); lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AA; } if (lookup->adflag) { debug("AD query"); lookup->sendmsg->flags |= DNS_MESSAGEFLAG_AD; } if (lookup->cdflag) { debug("CD query"); lookup->sendmsg->flags |= DNS_MESSAGEFLAG_CD; } dns_message_addname(lookup->sendmsg, lookup->name, DNS_SECTION_QUESTION); if (lookup->trace && lookup->trace_root) { lookup->qrdtype = lookup->rdtype; lookup->rdtype = dns_rdatatype_ns; } if ((lookup->rdtype == dns_rdatatype_axfr) || (lookup->rdtype == dns_rdatatype_ixfr)) { lookup->doing_xfr = ISC_TRUE; /* * Force TCP mode if we're doing an xfr. * XXX UDP ixfr's would be useful */ lookup->tcp_mode = ISC_TRUE; } add_question(lookup->sendmsg, lookup->name, lookup->rdclass, lookup->rdtype); /* add_soa */ if (lookup->rdtype == dns_rdatatype_ixfr) insert_soa(lookup); /* XXX Insist this? */ lookup->tsigctx = NULL; lookup->querysig = NULL; if (key != NULL) { debug("initializing keys"); result = dns_message_settsigkey(lookup->sendmsg, key); check_result(result, "dns_message_settsigkey"); } lookup->sendspace = isc_mempool_get(commctx); if (lookup->sendspace == NULL) fatal("memory allocation failure"); result = dns_compress_init(&cctx, -1, mctx); check_result(result, "dns_compress_init"); debug("starting to render the message"); isc_buffer_init(&lookup->sendbuf, lookup->sendspace, COMMSIZE); result = dns_message_renderbegin(lookup->sendmsg, &cctx, &lookup->sendbuf); check_result(result, "dns_message_renderbegin"); if (lookup->udpsize > 0 || lookup->dnssec) { if (lookup->udpsize == 0) lookup->udpsize = 2048; add_opt(lookup->sendmsg, lookup->udpsize, lookup->dnssec); } result = dns_message_rendersection(lookup->sendmsg, DNS_SECTION_QUESTION, 0); check_result(result, "dns_message_rendersection"); result = dns_message_rendersection(lookup->sendmsg, DNS_SECTION_AUTHORITY, 0); check_result(result, "dns_message_rendersection"); result = dns_message_renderend(lookup->sendmsg); check_result(result, "dns_message_renderend"); debug("done rendering"); dns_compress_invalidate(&cctx); /* * Force TCP mode if the request is larger than 512 bytes. */ if (isc_buffer_usedlength(&lookup->sendbuf) > 512) lookup->tcp_mode = ISC_TRUE; lookup->pending = ISC_FALSE; for (serv = ISC_LIST_HEAD(lookup->my_server_list); serv != NULL; serv = ISC_LIST_NEXT(serv, link)) { query = isc_mem_allocate(mctx, sizeof(dig_query_t)); if (query == NULL) fatal("memory allocation failure in %s:%d", __FILE__, __LINE__); debug("create query %p linked to lookup %p", query, lookup); query->lookup = lookup; query->waiting_connect = ISC_FALSE; query->recv_made = ISC_FALSE; query->first_pass = ISC_TRUE; query->first_soa_rcvd = ISC_FALSE; query->second_rr_rcvd = ISC_FALSE; query->first_repeat_rcvd = ISC_FALSE; query->warn_id = ISC_TRUE; query->first_rr_serial = 0; query->second_rr_serial = 0; query->servname = serv->servername; query->rr_count = 0; query->msg_count = 0; ISC_LINK_INIT(query, link); ISC_LIST_INIT(query->recvlist); ISC_LIST_INIT(query->lengthlist); query->sock = NULL; query->recvspace = isc_mempool_get(commctx); if (query->recvspace == NULL) fatal("memory allocation failure"); isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); isc_buffer_init(&query->lengthbuf, query->lengthspace, 2); isc_buffer_init(&query->slbuf, query->slspace, 2); ISC_LINK_INIT(query, link); ISC_LIST_ENQUEUE(lookup->q, query, link); } /* XXX qrflag, print_query, etc... */ if (!ISC_LIST_EMPTY(lookup->q) && qr) { printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg, ISC_TRUE); }}/* * Event handler for send completion. Track send counter, and clear out * the query if the send was canceled. */static voidsend_done(isc_task_t *_task, isc_event_t *event) { REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); UNUSED(_task); LOCK_LOOKUP; isc_event_free(&event); debug("send_done()"); sendcount--; debug("sendcount=%d", sendcount); INSIST(sendcount >= 0); check_if_done(); UNLOCK_LOOKUP;}/* * Cancel a lookup, sending isc_socket_cancel() requests to all outstanding * IO sockets. The cancel handlers should take care of cleaning up the * query and lookup structures */static voidcancel_lookup(dig_lookup_t *lookup) { dig_query_t *query, *next; debug("cancel_lookup()"); query = ISC_LIST_HEAD(lookup->q); while (query != NULL) { next = ISC_LIST_NEXT(query, link); if (query->sock != NULL) { isc_socket_cancel(query->sock, global_task, ISC_SOCKCANCEL_ALL); check_if_done(); } else { clear_query(query); } query = next; } if (lookup->timer != NULL) isc_timer_detach(&lookup->timer); lookup->pending = ISC_FALSE; lookup->retries = 0;}static voidbringup_timer(dig_query_t *query, unsigned int default_timeout) { dig_lookup_t *l; unsigned int local_timeout; isc_result_t result; debug("bringup_timer()"); /* * If the timer already exists, that means we're calling this * a second time (for a retry). Don't need to recreate it, * just reset it. */ l = query->lookup; if (ISC_LIST_NEXT(query, link) != NULL) local_timeout = SERVER_TIMEOUT; else { if (timeout == 0) { local_timeout = default_timeout; } else local_timeout = timeout;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -