static void process_answer(isc_task_t *task, isc_event_t *event) { struct query_trans *trans = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; isc_result_t result; REQUIRE(task == query_task); REQUIRE(trans->inuse == ISC_TRUE); REQUIRE(outstanding_queries > 0); printf("answer[%2d]\n", trans->id); if (rev->result != ISC_R_SUCCESS) printf(" failed: %d(%s)\n", rev->result, dns_result_totext(rev->result)); for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)printdata(rdataset, name); } } dns_client_freeresanswer(client, &rev->answerlist); dns_client_destroyrestrans(&trans->xid); isc_event_free(&event); trans->inuse = ISC_FALSE; dns_fixedname_invalidate(&trans->fixedname); trans->qname = NULL; outstanding_queries--; result = dispatch_query(trans); #if 0 /* for cancel test */ if (result == ISC_R_SUCCESS) { static int count = 0; if ((++count) % 10 == 0) dns_client_cancelresolve(trans->xid); } #endif if (result == ISC_R_NOMORE && outstanding_queries == 0) isc_app_ctxshutdown(query_actx); }
static void resolve_ns(isc_task_t *task, isc_event_t *event) { struct probe_trans *trans = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; isc_result_t result = ISC_R_SUCCESS; dns_rdata_t rdata = DNS_RDATA_INIT; struct probe_ns *pns; REQUIRE(task == probe_task); REQUIRE(trans->inuse == ISC_TRUE); INSIST(outstanding_probes > 0); for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)print_rdataset(rdataset, name); if (rdataset->type != dns_rdatatype_ns) continue; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_ns_t ns; dns_rdataset_current(rdataset, &rdata); /* * Extract the name from the NS record. */ result = dns_rdata_tostruct(&rdata, &ns, NULL); if (result != ISC_R_SUCCESS) continue; pns = isc_mem_get(mctx, sizeof(*pns)); if (pns == NULL) { fprintf(stderr, "resolve_ns: mem_get failed"); result = ISC_R_NOMEMORY; POST(result); /* * XXX: should we continue with the * available servers anyway? */ goto cleanup; } dns_fixedname_init(&pns->fixedname); pns->name = dns_fixedname_name(&pns->fixedname); ISC_LINK_INIT(pns, link); ISC_LIST_APPEND(trans->nslist, pns, link); ISC_LIST_INIT(pns->servers); dns_name_copy(&ns.name, pns->name, NULL); dns_rdata_reset(&rdata); dns_rdata_freestruct(&ns); } } } cleanup: dns_client_freeresanswer(client, &rev->answerlist); dns_client_destroyrestrans(&trans->resid); isc_event_free(&event); if (!ISC_LIST_EMPTY(trans->nslist)) { /* Go get addresses of NSes */ trans->current_ns = ISC_LIST_HEAD(trans->nslist); result = fetch_nsaddress(trans); } else result = ISC_R_FAILURE; if (result == ISC_R_SUCCESS) return; reset_probe(trans); }
static void resolve_nsaddress(isc_task_t *task, isc_event_t *event) { struct probe_trans *trans = event->ev_arg; dns_clientresevent_t *rev = (dns_clientresevent_t *)event; dns_name_t *name; dns_rdataset_t *rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; struct probe_ns *pns = trans->current_ns; isc_result_t result; REQUIRE(task == probe_task); REQUIRE(trans->inuse == ISC_TRUE); REQUIRE(pns != NULL); INSIST(outstanding_probes > 0); for (name = ISC_LIST_HEAD(rev->answerlist); name != NULL; name = ISC_LIST_NEXT(name, link)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { (void)print_rdataset(rdataset, name); if (rdataset->type != dns_rdatatype_a) continue; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdata_in_a_t rdata_a; struct server *server; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); if (result != ISC_R_SUCCESS) continue; server = isc_mem_get(mctx, sizeof(*server)); if (server == NULL) { fprintf(stderr, "resolve_nsaddress: " "mem_get failed"); result = ISC_R_NOMEMORY; POST(result); goto cleanup; } isc_sockaddr_fromin(&server->address, &rdata_a.in_addr, 53); ISC_LINK_INIT(server, link); server->result_a = none; server->result_aaaa = none; ISC_LIST_APPEND(pns->servers, server, link); } } } cleanup: dns_client_freeresanswer(client, &rev->answerlist); dns_client_destroyrestrans(&trans->resid); isc_event_free(&event); next_ns: trans->current_ns = ISC_LIST_NEXT(pns, link); if (trans->current_ns == NULL) { trans->current_ns = ISC_LIST_HEAD(trans->nslist); dns_fixedname_invalidate(&trans->fixedname); trans->qname = NULL; result = set_nextqname(trans); if (result == ISC_R_SUCCESS) result = probe_name(trans, dns_rdatatype_a); } else { result = fetch_nsaddress(trans); if (result != ISC_R_SUCCESS) goto next_ns; /* XXX: this is unlikely to succeed */ } if (result != ISC_R_SUCCESS) reset_probe(trans); }