Lines Matching defs:fctx
81 "fctx %p(%s): %s", fctx, fctx->info, (m))
87 "fctx %p(%s): %s %s", \
88 fctx, fctx->info, (m1), (m2))
93 "fetch %p (fctx %p(%s)): %s", \
100 "resquery %p (fctx %p(%s)): %s", \
101 query, query->fctx, \
102 query->fctx->info, (m))
129 fetchctx_t * fctx;
289 #define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC)
317 fetchctx_t * fctx;
357 #define DNS_BADCACHE_TTL(fctx) \
358 (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30)
444 static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
446 static void fctx_destroy(fetchctx_t *fctx);
447 static isc_boolean_t fctx_unlink(fetchctx_t *fctx);
457 static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
458 static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
460 static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name,
474 valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
483 valarg = isc_mem_get(fctx->mctx, sizeof(*valarg));
487 valarg->fctx = fctx;
490 if (!ISC_LIST_EMPTY(fctx->validators))
493 result = dns_validator_create(fctx->res->view, name, type, rdataset,
494 sigrdataset, fctx->rmessage,
498 inc_stats(fctx->res, dns_resstatscounter_val);
500 INSIST(fctx->validator == NULL);
501 fctx->validator = validator;
503 ISC_LIST_APPEND(fctx->validators, validator, link);
505 isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
510 rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
524 namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain,
534 fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
536 dns_name_t *domain = &fctx->domain;
577 (fctx->type == dns_rdatatype_ns ||
578 fctx->type == dns_rdatatype_ds ||
579 fctx->type == dns_rdatatype_soa ||
580 fctx->type == dns_rdatatype_any ||
581 fctx->type == dns_rdatatype_rrsig ||
582 fctx->type == dns_rdatatype_dnskey)) {
591 if (!dns_name_equal(name, &fctx->name))
598 rrsig_fromchildzone(fctx, rdataset))
603 if (fctx->type == type &&
612 if (fctx->type == dns_rdatatype_any &&
627 if (fctx->type == dns_rdatatype_ds &&
653 if (rrsig_fromchildzone(fctx, rdataset))
671 fctx->type == dns_rdatatype_any)
691 fctx_starttimer(fetchctx_t *fctx) {
693 * Start the lifetime timer for fctx.
699 return (isc_timer_reset(fctx->timer, isc_timertype_once,
700 &fctx->expires, NULL, ISC_TRUE));
704 fctx_stoptimer(fetchctx_t *fctx) {
713 result = isc_timer_reset(fctx->timer, isc_timertype_inactive,
724 fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) {
726 * Start the idle timer for fctx. The lifetime timer continues
729 return (isc_timer_reset(fctx->timer, isc_timertype_once,
730 &fctx->expires, interval, ISC_FALSE));
750 query->fctx->nqueries--;
751 if (SHUTTINGDOWN(query->fctx)) {
752 dns_resolver_t *res = query->fctx->res;
753 if (maybe_destroy(query->fctx, ISC_FALSE))
765 fetchctx_t *fctx;
774 fctx = query->fctx;
797 inc_stats(fctx->res,
800 inc_stats(fctx->res,
803 inc_stats(fctx->res,
806 inc_stats(fctx->res,
809 inc_stats(fctx->res,
812 inc_stats(fctx->res,
830 dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
835 dns_adb_changeflags(fctx->adb, query->addrinfo,
844 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
848 dns_adb_adjustsrtt(fctx->adb, addrinfo,
851 if (finish != NULL && TRIEDFIND(fctx))
852 for (find = ISC_LIST_HEAD(fctx->finds);
859 dns_adb_adjustsrtt(fctx->adb, addrinfo,
862 if (finish != NULL && TRIEDALT(fctx)) {
863 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
867 dns_adb_adjustsrtt(fctx->adb, addrinfo,
869 for (find = ISC_LIST_HEAD(fctx->altfinds);
876 dns_adb_adjustsrtt(fctx->adb, addrinfo,
915 ISC_LIST_UNLINK(fctx->queries, query, link);
934 fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
939 for (query = ISC_LIST_HEAD(fctx->queries);
948 fctx_cleanupfinds(fetchctx_t *fctx) {
951 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
953 for (find = ISC_LIST_HEAD(fctx->finds);
957 ISC_LIST_UNLINK(fctx->finds, find, publink);
960 fctx->find = NULL;
964 fctx_cleanupaltfinds(fetchctx_t *fctx) {
967 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
969 for (find = ISC_LIST_HEAD(fctx->altfinds);
973 ISC_LIST_UNLINK(fctx->altfinds, find, publink);
976 fctx->altfind = NULL;
980 fctx_cleanupforwaddrs(fetchctx_t *fctx) {
983 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
985 for (addr = ISC_LIST_HEAD(fctx->forwaddrs);
989 ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
990 dns_adb_freeaddrinfo(fctx->adb, &addr);
995 fctx_cleanupaltaddrs(fetchctx_t *fctx) {
998 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
1000 for (addr = ISC_LIST_HEAD(fctx->altaddrs);
1004 ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);
1005 dns_adb_freeaddrinfo(fctx->adb, &addr);
1010 fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) {
1012 fctx_cancelqueries(fctx, no_response);
1013 fctx_cleanupfinds(fctx);
1014 fctx_cleanupaltfinds(fctx);
1015 fctx_cleanupforwaddrs(fctx);
1016 fctx_cleanupaltaddrs(fctx);
1017 fctx_stoptimer(fctx);
1021 fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
1035 REQUIRE(fctx->state == fetchstate_done);
1042 fctx->result = result;
1043 fctx->exitline = line;
1045 fctx->duration = isc_time_microdiff(&now, &fctx->start);
1047 for (event = ISC_LIST_HEAD(fctx->events);
1051 ISC_LIST_UNLINK(fctx->events, event, ev_link);
1053 event->ev_sender = fctx;
1054 if (!HAVE_ANSWER(fctx))
1059 fctx->type == dns_rdatatype_any ||
1060 fctx->type == dns_rdatatype_rrsig ||
1061 fctx->type == dns_rdatatype_sig);
1076 if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 &&
1077 fctx->spilled &&
1078 (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) {
1079 LOCK(&fctx->res->lock);
1080 if (count == fctx->res->spillat && !fctx->res->exiting) {
1081 old_spillat = fctx->res->spillat;
1082 fctx->res->spillat += 5;
1083 if (fctx->res->spillat > fctx->res->spillatmax &&
1084 fctx->res->spillatmax != 0)
1085 fctx->res->spillat = fctx->res->spillatmax;
1086 new_spillat = fctx->res->spillat;
1091 result = isc_timer_reset(fctx->res->spillattimer,
1096 UNLOCK(&fctx->res->lock);
1106 log_edns(fetchctx_t *fctx) {
1109 if (fctx->reason == NULL)
1113 * We do not know if fctx->domain is the actual domain the record
1116 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
1120 fctx->info, domainbuf, fctx->reason);
1122 fctx->reason = NULL;
1126 fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
1134 res = fctx->res;
1140 log_edns(fctx);
1145 fctx->reason = NULL;
1146 fctx_stopeverything(fctx, no_response);
1148 LOCK(&res->buckets[fctx->bucketnum].lock);
1150 fctx->state = fetchstate_done;
1151 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
1152 fctx_sendevents(fctx, result, line);
1154 UNLOCK(&res->buckets[fctx->bucketnum].lock);
1162 fetchctx_t *fctx;
1164 fctx = query->fctx;
1190 add_bad(fctx, query->addrinfo, sevent->result,
1209 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
1210 result = fctx_stopidletimer(fctx);
1212 fctx_done(fctx, result, __LINE__);
1214 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
1275 fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
1283 if (fctx->restarts < 3)
1286 us = (800000 << (fctx->restarts - 2));
1307 isc_interval_set(&fctx->interval, seconds, us * 1000);
1311 fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
1324 res = fctx->res;
1325 task = res->buckets[fctx->bucketnum].task;
1331 fctx_setretryinterval(fctx, srtt);
1332 result = fctx_startidletimer(fctx, &fctx->interval);
1336 INSIST(ISC_LIST_EMPTY(fctx->validators));
1338 dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
1340 query = isc_mem_get(fctx->mctx, sizeof(*query));
1345 query->mctx = fctx->mctx;
1474 query->fctx = fctx;
1498 fctx->querysent++;
1500 ISC_LIST_APPEND(fctx->queries, query, link);
1501 query->fctx->nqueries++;
1508 fctx->type);
1522 isc_mem_put(fctx->mctx, query, sizeof(*query));
1526 RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS);
1532 bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1535 for (sa = ISC_LIST_HEAD(fctx->bad_edns);
1546 add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1549 if (bad_edns(fctx, address))
1552 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
1557 ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link);
1561 triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1564 for (sa = ISC_LIST_HEAD(fctx->edns);
1575 add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1578 if (triededns(fctx, address))
1581 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
1586 ISC_LIST_INITANDAPPEND(fctx->edns, sa, link);
1590 triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
1593 for (sa = ISC_LIST_HEAD(fctx->edns512);
1604 add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
1607 if (triededns512(fctx, address))
1610 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
1615 ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link);
1620 fetchctx_t *fctx;
1642 fctx = query->fctx;
1645 res = fctx->res;
1646 task = res->buckets[fctx->bucketnum].task;
1663 result = dns_message_gettempname(fctx->qmessage, &qname);
1666 result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset);
1684 fctx->qmessage->opcode = dns_opcode_query;
1690 dns_name_clone(&fctx->name, qname);
1692 dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
1694 dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
1704 fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
1711 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
1714 &fctx->name,
1721 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
1727 fctx->qmessage->id = query->id;
1732 result = dns_compress_init(&cctx, -1, fctx->res->mctx);
1737 result = dns_message_renderbegin(fctx->qmessage, &cctx,
1742 result = dns_message_rendersection(fctx->qmessage,
1749 (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
1761 dns_adb_changeflags(fctx->adb, query->addrinfo,
1784 if (fctx->timeout) {
1785 if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
1786 fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
1789 fctx->reason = "disabling EDNS";
1790 } else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
1791 fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
1794 fctx->reason = "reducing the advertised EDNS UDP "
1797 fctx->timeout = ISC_FALSE;
1831 result = fctx_addopt(fctx->qmessage, version,
1856 if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
1862 add_triededns(fctx, &query->addrinfo->sockaddr);
1865 add_triededns512(fctx, &query->addrinfo->sockaddr);
1871 fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD;
1876 result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey);
1881 result = dns_message_settsigkey(fctx->qmessage, tsigkey);
1887 result = dns_message_rendersection(fctx->qmessage,
1892 result = dns_message_renderend(fctx->qmessage);
1899 if (dns_message_gettsigkey(fctx->qmessage) != NULL) {
1900 dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage),
1902 result = dns_message_getquerytsig(fctx->qmessage,
1903 fctx->res->mctx,
1922 dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
1957 * Keep fctx around until the event is processed.
1959 query->fctx->nqueries++;
1975 dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
1984 dns_message_puttempname(fctx->qmessage, &qname);
1986 dns_message_puttemprdataset(fctx->qmessage, &qrdataset);
1999 fetchctx_t *fctx;
2017 fctx = query->fctx;
2037 result = fctx_startidletimer(query->fctx, &interval);
2040 fctx_done(fctx, result, __LINE__);
2060 query->fctx->res->taskmgr,
2076 fctx_done(fctx, result, __LINE__);
2108 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
2109 result = fctx_stopidletimer(fctx);
2111 fctx_done(fctx, result, __LINE__);
2113 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
2119 fetchctx_t *fctx;
2129 fctx = event->ev_arg;
2130 REQUIRE(VALID_FCTX(fctx));
2131 res = fctx->res;
2137 bucketnum = fctx->bucketnum;
2140 INSIST(fctx->pending > 0);
2141 fctx->pending--;
2143 if (ADDRWAIT(fctx)) {
2147 INSIST(!SHUTTINGDOWN(fctx));
2148 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
2152 fctx->findfail++;
2153 if (fctx->pending == 0) {
2157 * fail the fctx.
2162 } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
2163 fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
2165 if (fctx->references == 0) {
2166 bucket_empty = fctx_unlink(fctx);
2176 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
2178 fctx_done(fctx, ISC_R_FAILURE, __LINE__);
2180 fctx_destroy(fctx);
2188 bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) {
2191 for (sa = ISC_LIST_HEAD(fctx->bad);
2202 mark_bad(fetchctx_t *fctx) {
2215 for (curr = ISC_LIST_HEAD(fctx->finds);
2221 if (bad_server(fctx, &addrinfo->sockaddr))
2231 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
2234 if (bad_server(fctx, &addrinfo->sockaddr))
2243 for (curr = ISC_LIST_HEAD(fctx->altfinds);
2249 if (bad_server(fctx, &addrinfo->sockaddr))
2256 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
2259 if (bad_server(fctx, &addrinfo->sockaddr))
2269 add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
2283 fctx->lamecount++;
2287 fctx->neterr++;
2290 fctx->badresp++;
2297 if (bad_server(fctx, address)) {
2306 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
2310 ISC_LIST_INITANDAPPEND(fctx->bad, sa, link);
2316 fctx->rmessage->rcode == dns_rcode_servfail &&
2322 dns_rcode_totext(fctx->rmessage->rcode, &b);
2328 dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b);
2337 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
2338 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
2339 dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf));
2349 * Return 'bits' bits of random entropy from fctx->rand_buf,
2354 random_bits(fetchctx_t *fctx, isc_uint32_t bits) {
2357 REQUIRE(VALID_FCTX(fctx));
2362 if (bits >= fctx->rand_bits) {
2364 bits -= fctx->rand_bits;
2365 ret = fctx->rand_buf << bits;
2368 isc_random_get(&fctx->rand_buf);
2369 fctx->rand_bits = sizeof(fctx->rand_buf) * CHAR_BIT;
2378 ret |= fctx->rand_buf & mask;
2379 fctx->rand_buf >>= bits;
2380 fctx->rand_bits -= bits;
2396 randomize_srtt(fetchctx_t *fctx, dns_adbaddrinfo_t *ai) {
2399 ai->srtt |= (ai->srtt & 0x80) | random_bits(fctx, 7);
2402 ai->srtt = random_bits(fctx, 3) << 10;
2409 sort_adbfind(fetchctx_t *fctx, dns_adbfind_t *find) {
2416 randomize_srtt(fctx, curr);
2440 sort_finds(fetchctx_t *fctx, dns_adbfindlist_t *findlist) {
2449 sort_adbfind(fctx, curr);
2474 findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
2484 res = fctx->res;
2485 unshared = ISC_TF((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
2493 if (dns_name_issubdomain(name, &fctx->domain))
2502 result = dns_adb_createfind(fctx->adb,
2503 res->buckets[fctx->bucketnum].task,
2504 fctx_finddone, fctx, name,
2505 &fctx->name, fctx->type,
2514 fctx->adberr++;
2533 ISC_LIST_APPEND(fctx->altfinds, find, publink);
2535 ISC_LIST_APPEND(fctx->finds, find, publink);
2546 fctx->pending++;
2559 fctx->lamecount++; /* cached lame server */
2561 fctx->adberr++; /* unreachable server, etc. */
2590 fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
2607 fctx->restarts++;
2608 if (fctx->restarts > 10) {
2613 res = fctx->res;
2619 INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
2620 INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
2623 * If this fctx has forwarders, use them; otherwise use any
2627 sa = ISC_LIST_HEAD(fctx->forwarders);
2630 dns_name_t *name = &fctx->name;
2640 if (dns_rdatatype_atparent(fctx->type) &&
2650 result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
2654 fctx->fwdpolicy = forwarders->fwdpolicy;
2655 if (fctx->fwdpolicy == dns_fwdpolicy_only &&
2656 isstrictsubdomain(domain, &fctx->domain)) {
2657 dns_name_free(&fctx->domain, fctx->mctx);
2658 dns_name_init(&fctx->domain, NULL);
2659 result = dns_name_dup(domain, fctx->mctx,
2660 &fctx->domain);
2669 fctx->res->dispatchv4 == NULL) ||
2671 fctx->res->dispatchv6 == NULL)) {
2676 result = dns_adb_findaddrinfo(fctx->adb,
2681 cur = ISC_LIST_HEAD(fctx->forwaddrs);
2685 ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur,
2688 ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
2697 if (fctx->fwdpolicy == dns_fwdpolicy_only)
2705 if (fctx->restarts == 1) {
2714 * if fctx->restarts > 1, we've clearly been having trouble
2725 INSIST(ISC_LIST_EMPTY(fctx->finds));
2726 INSIST(ISC_LIST_EMPTY(fctx->altfinds));
2728 for (result = dns_rdataset_first(&fctx->nameservers);
2730 result = dns_rdataset_next(&fctx->nameservers))
2732 dns_rdataset_current(&fctx->nameservers, &rdata);
2740 findname(fctx, &ns.name, 0, stdoptions, 0, now,
2755 for (a = ISC_LIST_HEAD(fctx->res->alternates);
2759 findname(fctx, &a->_u._n.name, a->_u._n.port,
2767 result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr,
2772 cur = ISC_LIST_HEAD(fctx->altaddrs);
2776 ISC_LIST_INSERTBEFORE(fctx->altaddrs,
2779 ISC_LIST_APPEND(fctx->altaddrs, ai,
2789 all_bad = mark_bad(fctx);
2798 if (fctx->pending > 0) {
2813 isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
2816 (fctx->type == dns_rdatatype_dnskey ||
2817 fctx->type == dns_rdatatype_dlv ||
2818 fctx->type == dns_rdatatype_ds) &&
2820 dns_resolver_addbadcache(fctx->res,
2821 &fctx->name,
2822 fctx->type, &expire);
2830 sort_finds(fctx, &fctx->finds);
2831 sort_finds(fctx, &fctx->altfinds);
2839 possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr)
2854 res = fctx->res;
2903 fctx_nextaddress(fetchctx_t *fctx) {
2915 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
2920 possibly_mark(fctx, addrinfo);
2923 fctx->find = NULL;
2932 fctx->attributes |= FCTX_ATTR_TRIEDFIND;
2934 find = fctx->find;
2936 find = ISC_LIST_HEAD(fctx->finds);
2940 find = ISC_LIST_HEAD(fctx->finds);
2955 possibly_mark(fctx, addrinfo);
2965 find = ISC_LIST_HEAD(fctx->finds);
2969 fctx->find = find;
2977 fctx->attributes |= FCTX_ATTR_TRIEDALT;
2979 find = fctx->altfind;
2981 find = ISC_LIST_HEAD(fctx->altfinds);
2985 find = ISC_LIST_HEAD(fctx->altfinds);
3000 possibly_mark(fctx, addrinfo);
3010 find = ISC_LIST_HEAD(fctx->altfinds);
3020 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
3025 possibly_mark(fctx, addrinfo);
3038 fctx->altfind = find;
3045 fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
3051 REQUIRE(!ADDRWAIT(fctx));
3053 addrinfo = fctx_nextaddress(fctx);
3058 fctx_cancelqueries(fctx, ISC_TRUE);
3059 fctx_cleanupfinds(fctx);
3060 fctx_cleanupaltfinds(fctx);
3061 fctx_cleanupforwaddrs(fctx);
3062 fctx_cleanupaltaddrs(fctx);
3063 result = fctx_getaddresses(fctx, badcache);
3069 fctx->attributes |= FCTX_ATTR_ADDRWAIT;
3075 fctx_done(fctx, result, __LINE__);
3079 addrinfo = fctx_nextaddress(fctx);
3085 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
3090 result = fctx_query(fctx, addrinfo, fctx->options);
3092 fctx_done(fctx, result, __LINE__);
3094 inc_stats(fctx->res, dns_resstatscounter_retry);
3098 fctx_unlink(fetchctx_t *fctx) {
3106 REQUIRE(VALID_FCTX(fctx));
3107 REQUIRE(fctx->state == fetchstate_done ||
3108 fctx->state == fetchstate_init);
3109 REQUIRE(ISC_LIST_EMPTY(fctx->events));
3110 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
3111 REQUIRE(ISC_LIST_EMPTY(fctx->finds));
3112 REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
3113 REQUIRE(fctx->pending == 0);
3114 REQUIRE(fctx->references == 0);
3115 REQUIRE(ISC_LIST_EMPTY(fctx->validators));
3119 res = fctx->res;
3120 bucketnum = fctx->bucketnum;
3122 ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
3136 fctx_destroy(fetchctx_t *fctx) {
3139 REQUIRE(VALID_FCTX(fctx));
3140 REQUIRE(fctx->state == fetchstate_done ||
3141 fctx->state == fetchstate_init);
3142 REQUIRE(ISC_LIST_EMPTY(fctx->events));
3143 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
3144 REQUIRE(ISC_LIST_EMPTY(fctx->finds));
3145 REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
3146 REQUIRE(fctx->pending == 0);
3147 REQUIRE(fctx->references == 0);
3148 REQUIRE(ISC_LIST_EMPTY(fctx->validators));
3149 REQUIRE(!ISC_LINK_LINKED(fctx, link));
3156 for (sa = ISC_LIST_HEAD(fctx->bad);
3160 ISC_LIST_UNLINK(fctx->bad, sa, link);
3161 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3164 for (sa = ISC_LIST_HEAD(fctx->edns);
3168 ISC_LIST_UNLINK(fctx->edns, sa, link);
3169 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3172 for (sa = ISC_LIST_HEAD(fctx->edns512);
3176 ISC_LIST_UNLINK(fctx->edns512, sa, link);
3177 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3180 for (sa = ISC_LIST_HEAD(fctx->bad_edns);
3184 ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
3185 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3188 isc_timer_detach(&fctx->timer);
3189 dns_message_destroy(&fctx->rmessage);
3190 dns_message_destroy(&fctx->qmessage);
3191 if (dns_name_countlabels(&fctx->domain) > 0)
3192 dns_name_free(&fctx->domain, fctx->mctx);
3193 if (dns_rdataset_isassociated(&fctx->nameservers))
3194 dns_rdataset_disassociate(&fctx->nameservers);
3195 dns_name_free(&fctx->name, fctx->mctx);
3196 dns_db_detach(&fctx->cache);
3197 dns_adb_detach(&fctx->adb);
3198 isc_mem_free(fctx->mctx, fctx->info);
3199 isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
3208 fetchctx_t *fctx = event->ev_arg;
3212 REQUIRE(VALID_FCTX(fctx));
3218 inc_stats(fctx->res, dns_resstatscounter_querytimeout);
3221 fctx->reason = NULL;
3222 fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__);
3226 fctx->timeouts++;
3227 fctx->timeout = ISC_TRUE;
3237 query = ISC_LIST_HEAD(fctx->queries);
3242 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
3244 * Our timer has triggered. Reestablish the fctx lifetime
3247 result = fctx_starttimer(fctx);
3249 fctx_done(fctx, result, __LINE__);
3254 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
3261 fctx_shutdown(fetchctx_t *fctx) {
3265 * Start the shutdown process for fctx, if it isn't already underway.
3274 if (fctx->want_shutdown)
3277 fctx->want_shutdown = ISC_TRUE;
3285 if (fctx->state != fetchstate_init) {
3286 cevent = &fctx->control_event;
3287 isc_task_send(fctx->res->buckets[fctx->bucketnum].task,
3294 fetchctx_t *fctx = event->ev_arg;
3301 REQUIRE(VALID_FCTX(fctx));
3305 res = fctx->res;
3306 bucketnum = fctx->bucketnum;
3311 * An fctx that is shutting down is no longer in ADDRWAIT mode.
3313 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
3319 validator = ISC_LIST_HEAD(fctx->validators);
3325 if (fctx->nsfetch != NULL)
3326 dns_resolver_cancelfetch(fctx->nsfetch);
3333 fctx_stopeverything(fctx, ISC_FALSE);
3337 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
3339 INSIST(fctx->state == fetchstate_active ||
3340 fctx->state == fetchstate_done);
3341 INSIST(fctx->want_shutdown);
3343 if (fctx->state != fetchstate_done) {
3344 fctx->state = fetchstate_done;
3345 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
3348 if (fctx->references == 0 && fctx->pending == 0 &&
3349 fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
3350 bucket_empty = fctx_unlink(fctx);
3357 fctx_destroy(fctx);
3365 fetchctx_t *fctx = event->ev_arg;
3371 REQUIRE(VALID_FCTX(fctx));
3375 res = fctx->res;
3376 bucketnum = fctx->bucketnum;
3382 INSIST(fctx->state == fetchstate_init);
3383 if (fctx->want_shutdown) {
3385 * We haven't started this fctx yet, and we've been requested
3388 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
3389 fctx->state = fetchstate_done;
3390 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
3395 INSIST(fctx->pending == 0);
3396 INSIST(fctx->nqueries == 0);
3397 INSIST(ISC_LIST_EMPTY(fctx->validators));
3398 if (fctx->references == 0) {
3400 * It's now safe to destroy this fctx.
3402 bucket_empty = fctx_unlink(fctx);
3408 * Normal fctx startup.
3410 fctx->state = fetchstate_active;
3413 * the fctx.
3416 DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx,
3430 result = fctx_starttimer(fctx);
3432 fctx_done(fctx, result, __LINE__);
3434 fctx_try(fctx, ISC_FALSE, ISC_FALSE);
3436 fctx_destroy(fctx);
3447 fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client,
3465 isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE,
3472 event->qtype = fctx->type;
3487 ISC_LIST_PREPEND(fctx->events, event, ev_link);
3489 ISC_LIST_APPEND(fctx->events, event, ev_link);
3490 fctx->references++;
3493 fetch->private = fctx;
3499 log_ns_ttl(fetchctx_t *fctx, const char *where) {
3503 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
3504 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
3507 "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u",
3508 fctx, where, namebuf, domainbuf,
3509 fctx->ns_ttl_ok, fctx->ns_ttl);
3517 fetchctx_t *fctx;
3534 fctx = isc_mem_get(mctx, sizeof(*fctx));
3535 if (fctx == NULL)
3541 fctx->info = isc_mem_strdup(mctx, buf);
3542 if (fctx->info == NULL) {
3547 dns_name_init(&fctx->name, NULL);
3548 result = dns_name_dup(name, mctx, &fctx->name);
3551 dns_name_init(&fctx->domain, NULL);
3552 dns_rdataset_init(&fctx->nameservers);
3554 fctx->type = type;
3555 fctx->options = options;
3561 fctx->res = res;
3562 fctx->references = 0;
3563 fctx->bucketnum = bucketnum;
3564 fctx->state = fetchstate_init;
3565 fctx->want_shutdown = ISC_FALSE;
3566 fctx->cloned = ISC_FALSE;
3567 ISC_LIST_INIT(fctx->queries);
3568 ISC_LIST_INIT(fctx->finds);
3569 ISC_LIST_INIT(fctx->altfinds);
3570 ISC_LIST_INIT(fctx->forwaddrs);
3571 ISC_LIST_INIT(fctx->altaddrs);
3572 ISC_LIST_INIT(fctx->forwarders);
3573 fctx->fwdpolicy = dns_fwdpolicy_none;
3574 ISC_LIST_INIT(fctx->bad);
3575 ISC_LIST_INIT(fctx->edns);
3576 ISC_LIST_INIT(fctx->edns512);
3577 ISC_LIST_INIT(fctx->bad_edns);
3578 ISC_LIST_INIT(fctx->validators);
3579 fctx->validator = NULL;
3580 fctx->find = NULL;
3581 fctx->altfind = NULL;
3582 fctx->pending = 0;
3583 fctx->restarts = 0;
3584 fctx->querysent = 0;
3585 fctx->referrals = 0;
3586 TIME_NOW(&fctx->start);
3587 fctx->timeouts = 0;
3588 fctx->lamecount = 0;
3589 fctx->adberr = 0;
3590 fctx->neterr = 0;
3591 fctx->badresp = 0;
3592 fctx->findfail = 0;
3593 fctx->valfail = 0;
3594 fctx->result = ISC_R_FAILURE;
3595 fctx->vresult = ISC_R_SUCCESS;
3596 fctx->exitline = -1; /* sentinel */
3597 fctx->logged = ISC_FALSE;
3598 fctx->attributes = 0;
3599 fctx->spilled = ISC_FALSE;
3600 fctx->nqueries = 0;
3601 fctx->reason = NULL;
3602 fctx->rand_buf = 0;
3603 fctx->rand_bits = 0;
3604 fctx->timeout = ISC_FALSE;
3605 fctx->addrinfo = NULL;
3606 fctx->ns_ttl = 0;
3607 fctx->ns_ttl_ok = ISC_FALSE;
3609 dns_name_init(&fctx->nsname, NULL);
3610 fctx->nsfetch = NULL;
3611 dns_rdataset_init(&fctx->nsrrset);
3622 if (dns_rdatatype_atparent(fctx->type) &&
3631 result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname,
3634 fctx->fwdpolicy = forwarders->fwdpolicy;
3636 if (fctx->fwdpolicy != dns_fwdpolicy_only) {
3642 if (dns_rdatatype_atparent(fctx->type))
3646 &fctx->nameservers,
3650 result = dns_name_dup(domain, mctx, &fctx->domain);
3652 dns_rdataset_disassociate(&fctx->nameservers);
3655 fctx->ns_ttl = fctx->nameservers.ttl;
3656 fctx->ns_ttl_ok = ISC_TRUE;
3661 result = dns_name_dup(domain, mctx, &fctx->domain);
3666 result = dns_name_dup(domain, mctx, &fctx->domain);
3669 dns_rdataset_clone(nameservers, &fctx->nameservers);
3670 fctx->ns_ttl = fctx->nameservers.ttl;
3671 fctx->ns_ttl_ok = ISC_TRUE;
3674 log_ns_ttl(fctx, "fctx_create");
3676 INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
3678 fctx->qmessage = NULL;
3680 &fctx->qmessage);
3685 fctx->rmessage = NULL;
3687 &fctx->rmessage);
3696 iresult = isc_time_nowplusinterval(&fctx->expires, &interval);
3710 isc_interval_set(&fctx->interval, 2, 0);
3716 fctx->timer = NULL;
3720 fctx, &fctx->timer);
3732 fctx->cache = NULL;
3733 dns_db_attach(res->view->cachedb, &fctx->cache);
3734 fctx->adb = NULL;
3735 dns_adb_attach(res->view->adb, &fctx->adb);
3736 fctx->mctx = NULL;
3737 isc_mem_attach(mctx, &fctx->mctx);
3739 ISC_LIST_INIT(fctx->events);
3740 ISC_LINK_INIT(fctx, link);
3741 fctx->magic = FCTX_MAGIC;
3743 ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
3749 *fctxp = fctx;
3754 dns_message_destroy(&fctx->rmessage);
3757 dns_message_destroy(&fctx->qmessage);
3760 if (dns_name_countlabels(&fctx->domain) > 0)
3761 dns_name_free(&fctx->domain, mctx);
3762 if (dns_rdataset_isassociated(&fctx->nameservers))
3763 dns_rdataset_disassociate(&fctx->nameservers);
3766 dns_name_free(&fctx->name, mctx);
3769 isc_mem_free(mctx, fctx->info);
3772 isc_mem_put(mctx, fctx, sizeof(*fctx));
3781 is_lame(fetchctx_t *fctx) {
3782 dns_message_t *message = fctx->rmessage;
3809 namereln = dns_name_fullcompare(name, &fctx->domain,
3825 log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
3830 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
3831 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
3840 same_question(fetchctx_t *fctx) {
3842 dns_message_t *message = fctx->rmessage;
3847 * Caller must be holding the fctx lock.
3864 if (fctx->type != rdataset->type ||
3865 fctx->res->rdclass != rdataset->rdclass ||
3866 !dns_name_equal(&fctx->name, name))
3873 clone_results(fetchctx_t *fctx) {
3887 fctx->cloned = ISC_TRUE;
3888 hevent = ISC_LIST_HEAD(fctx->events);
3927 * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has
3931 * '*fctx' is shutting down.
3934 * true if the resolver is exiting and this is the last fctx in the bucket.
3937 maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
3940 dns_resolver_t *res = fctx->res;
3944 REQUIRE(SHUTTINGDOWN(fctx));
3946 bucketnum = fctx->bucketnum;
3949 if (fctx->pending != 0 || fctx->nqueries != 0)
3952 for (validator = ISC_LIST_HEAD(fctx->validators);
3958 if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) {
3959 bucket_empty = fctx_unlink(fctx);
3966 fctx_destroy(fctx);
3987 fetchctx_t *fctx;
4000 fctx = valarg->fctx;
4001 res = fctx->res;
4003 REQUIRE(VALID_FCTX(fctx));
4004 REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
4010 LOCK(&res->buckets[fctx->bucketnum].lock);
4012 ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
4013 fctx->validator = NULL;
4017 * destroy the fctx if necessary.
4020 isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
4024 sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0);
4029 * so, destroy the fctx.
4031 if (SHUTTINGDOWN(fctx) && !sentresponse) {
4032 isc_uint32_t bucketnum = fctx->bucketnum;
4034 bucket_empty = maybe_destroy(fctx, ISC_TRUE);
4068 hevent = ISC_LIST_HEAD(fctx->events);
4071 (fctx->type == dns_rdatatype_any ||
4072 fctx->type == dns_rdatatype_rrsig ||
4073 fctx->type == dns_rdatatype_sig)) {
4087 fctx->valfail++;
4088 fctx->vresult = vevent->result;
4089 if (fctx->vresult != DNS_R_BROKENCHAIN) {
4092 result = dns_db_findnode(fctx->cache,
4096 (void)dns_db_deleterdataset(fctx->cache, node,
4101 (void)dns_db_deleterdataset(fctx->cache, node,
4106 dns_db_detachnode(fctx->cache, &node);
4108 if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) {
4114 result = dns_db_findnode(fctx->cache,
4118 (void)dns_db_addrdataset(fctx->cache, node,
4125 (void)dns_db_addrdataset(fctx->cache, node,
4130 dns_db_detachnode(fctx->cache, &node);
4132 result = fctx->vresult;
4133 add_bad(fctx, addrinfo, result, badns_validation);
4135 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4136 INSIST(fctx->validator == NULL);
4137 fctx->validator = ISC_LIST_HEAD(fctx->validators);
4138 if (fctx->validator != NULL)
4139 dns_validator_send(fctx->validator);
4141 fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4147 isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
4150 (fctx->type == dns_rdatatype_dnskey ||
4151 fctx->type == dns_rdatatype_dlv ||
4152 fctx->type == dns_rdatatype_ds) &&
4154 dns_resolver_addbadcache(res, &fctx->name,
4155 fctx->type, &expire);
4156 fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4158 fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */
4169 if (fctx->rmessage->rcode == dns_rcode_nxdomain)
4172 covers = fctx->type;
4174 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE,
4185 if (fctx->type == dns_rdatatype_soa &&
4189 result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
4216 tresult = findnoqname(fctx, vevent->name,
4231 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node);
4235 result = dns_db_addrdataset(fctx->cache, node, NULL, now,
4246 result = dns_db_addrdataset(fctx->cache, node, NULL, now,
4260 dns_db_detachnode(fctx->cache, &node);
4261 if (SHUTTINGDOWN(fctx))
4262 bucket_empty = maybe_destroy(fctx, ISC_TRUE);
4263 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4269 if (!ISC_LIST_EMPTY(fctx->validators)) {
4271 INSIST(fctx->type == dns_rdatatype_any ||
4272 fctx->type == dns_rdatatype_rrsig ||
4273 fctx->type == dns_rdatatype_sig);
4279 dns_db_detachnode(fctx->cache, &node);
4280 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4281 dns_validator_send(ISC_LIST_HEAD(fctx->validators));
4289 result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
4292 dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
4312 result = dns_db_findnode(fctx->cache, name, ISC_TRUE,
4317 result = dns_db_addrdataset(fctx->cache, nsnode, NULL,
4320 result = dns_db_addrdataset(fctx->cache, nsnode,
4324 dns_db_detachnode(fctx->cache, &nsnode);
4328 result = dns_message_nextname(fctx->rmessage,
4339 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4346 dns_db_attach(fctx->cache, &hevent->db);
4347 dns_db_transfernode(fctx->cache, &node, &hevent->node);
4348 clone_results(fctx);
4353 dns_db_detachnode(fctx->cache, &node);
4355 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4356 fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4367 fetchctx_t *fctx = arg;
4375 "fctx %p(%s): %s", fctx, fctx->info, msgbuf);
4379 findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
4444 for (result = dns_message_firstname(fctx->rmessage, section);
4446 result = dns_message_nextname(fctx->rmessage, section)) {
4448 dns_message_currentname(fctx->rmessage, section, &nsec);
4465 fctx)))
4481 fctx_log, fctx)))
4507 cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
4529 res = fctx->res;
4535 task = res->buckets[fctx->bucketnum].task;
4552 if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
4566 event = ISC_LIST_HEAD(fctx->events);
4581 if ((fctx->type != dns_rdatatype_any &&
4582 fctx->type != dns_rdatatype_rrsig &&
4583 fctx->type != dns_rdatatype_sig) ||
4595 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
4602 fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
4625 dns_db_detachnode(fctx->cache, &node);
4707 tresult = findnoqname(fctx, name,
4720 result = dns_db_addrdataset(fctx->cache, node,
4754 result = dns_db_addrdataset(fctx->cache,
4767 if (fctx->type != dns_rdatatype_any &&
4768 fctx->type != dns_rdatatype_rrsig &&
4769 fctx->type != dns_rdatatype_sig) {
4791 result = valcreate(fctx, addrinfo,
4799 * from manipulating fctx->rmessage
4851 tresult = findnoqname(fctx, name,
4864 result = dns_db_addrdataset(fctx->cache,
4892 result = valcreate(fctx, addrinfo, name, fctx->type,
4897 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4908 dns_db_attach(fctx->cache, adbp);
4909 dns_db_transfernode(fctx->cache, &node, anodep);
4910 clone_results(fctx);
4915 dns_db_detachnode(fctx->cache, &node);
4921 cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
4929 fctx->attributes &= ~FCTX_ATTR_WANTCACHE;
4931 LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4936 result = dns_message_firstname(fctx->rmessage, section);
4939 dns_message_currentname(fctx->rmessage, section,
4942 result = cache_name(fctx, name, addrinfo, now);
4946 result = dns_message_nextname(fctx->rmessage, section);
4954 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
5016 ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
5033 fctx->attributes &= ~FCTX_ATTR_WANTNCACHE;
5035 res = fctx->res;
5040 name = &fctx->name;
5047 INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0);
5052 if (fctx->res->view->enablevalidation) {
5064 if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
5076 result = dns_message_firstname(fctx->rmessage,
5080 dns_message_currentname(fctx->rmessage,
5087 result = dns_message_nextname(fctx->rmessage,
5099 result = valcreate(fctx, addrinfo, name, fctx->type,
5101 res->buckets[fctx->bucketnum].task);
5110 LOCK(&res->buckets[fctx->bucketnum].lock);
5116 if (!HAVE_ANSWER(fctx)) {
5117 event = ISC_LIST_HEAD(fctx->events);
5130 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
5139 ttl = fctx->res->view->maxncachettl;
5140 if (fctx->type == dns_rdatatype_soa &&
5142 fctx->res->zero_no_soa_ttl)
5145 result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
5151 if (!HAVE_ANSWER(fctx)) {
5152 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
5155 dns_db_attach(fctx->cache, adbp);
5156 dns_db_transfernode(fctx->cache, &node, anodep);
5157 clone_results(fctx);
5162 UNLOCK(&res->buckets[fctx->bucketnum].lock);
5165 dns_db_detachnode(fctx->cache, &node);
5199 fetchctx_t *fctx = arg;
5207 REQUIRE(VALID_FCTX(fctx));
5209 if (GLUING(fctx))
5215 result = dns_message_findname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
5219 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
5256 chase_additional(fetchctx_t *fctx) {
5264 for (result = dns_message_firstname(fctx->rmessage, section);
5266 result = dns_message_nextname(fctx->rmessage, section)) {
5269 dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
5281 fctx);
5353 trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) {
5358 if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) {
5360 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
5361 dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf));
5365 "fctx %p: trimming ttl of %s/NS for %s/%s: "
5366 "%u -> %u", fctx, ns_namebuf, namebuf, tbuf,
5367 rdataset->ttl, fctx->ns_ttl);
5368 rdataset->ttl = fctx->ns_ttl;
5380 noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
5394 message = fctx->rmessage;
5408 qname = &fctx->name;
5424 if (!dns_name_issubdomain(qname, &fctx->domain))
5454 if (dns_name_issubdomain(name, &fctx->domain)) {
5508 else if (ISFORWARDER(fctx->addrinfo))
5524 log_ns_ttl(fctx, "noanswer_response");
5526 if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
5528 trim_ns_ttl(fctx, ns_name, ns_rdataset);
5544 if (dns_name_issubdomain(name, &fctx->domain)) {
5570 else if (ISFORWARDER(fctx->addrinfo))
5604 else if (ISFORWARDER(fctx->addrinfo))
5624 fctx->type == dns_rdatatype_ds && soa_name != NULL &&
5663 * We already know ns_name is a subdomain of fctx->domain.
5664 * If ns_name is equal to fctx->domain, we're not making
5668 if (dns_name_equal(ns_name, &fctx->domain))
5675 if (! dns_name_issubdomain(&fctx->name, ns_name)) {
5686 fctx->attributes |= FCTX_ATTR_GLUING;
5688 fctx);
5689 fctx->attributes &= ~FCTX_ATTR_GLUING;
5705 INSIST(dns_name_countlabels(&fctx->domain) > 0);
5706 dns_name_free(&fctx->domain, fctx->mctx);
5707 if (dns_rdataset_isassociated(&fctx->nameservers))
5708 dns_rdataset_disassociate(&fctx->nameservers);
5709 dns_name_init(&fctx->domain, NULL);
5710 result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain);
5713 fctx->attributes |= FCTX_ATTR_WANTCACHE;
5714 fctx->ns_ttl_ok = ISC_FALSE;
5715 log_ns_ttl(fctx, "DELEGATION");
5727 fctx->attributes |= FCTX_ATTR_WANTNCACHE;
5733 answer_response(fetchctx_t *fctx) {
5746 message = fctx->rmessage;
5764 qname = &fctx->name;
5765 type = fctx->type;
5770 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
5893 fctx);
6059 fctx->attributes |= FCTX_ATTR_WANTCACHE;
6071 return (noanswer_response(fctx, qname, ISC_FALSE));
6094 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
6128 fctx);
6138 log_ns_ttl(fctx, "answer_response");
6140 if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
6142 trim_ns_ttl(fctx, ns_name, ns_rdataset);
6148 fctx_decreference(fetchctx_t *fctx) {
6151 INSIST(fctx->references > 0);
6152 fctx->references--;
6153 if (fctx->references == 0) {
6157 if (fctx->pending == 0 && fctx->nqueries == 0 &&
6158 ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) {
6160 * This fctx is already shutdown; we were just
6163 bucket_empty = fctx_unlink(fctx);
6164 fctx_destroy(fctx);
6169 fctx_shutdown(fctx);
6179 fetchctx_t *fctx;
6190 fctx = event->ev_arg;
6191 REQUIRE(VALID_FCTX(fctx));
6192 res = fctx->res;
6204 bucketnum = fctx->bucketnum;
6206 dns_resolver_destroyfetch(&fctx->nsfetch);
6207 fctx_done(fctx, ISC_R_CANCELED, __LINE__);
6212 dns_resolver_destroyfetch(&fctx->nsfetch);
6213 if (dns_rdataset_isassociated(&fctx->nameservers))
6214 dns_rdataset_disassociate(&fctx->nameservers);
6215 dns_rdataset_clone(fevent->rdataset, &fctx->nameservers);
6216 fctx->ns_ttl = fctx->nameservers.ttl;
6217 fctx->ns_ttl_ok = ISC_TRUE;
6218 log_ns_ttl(fctx, "resume_dslookup");
6219 dns_name_free(&fctx->domain, fctx->mctx);
6220 dns_name_init(&fctx->domain, NULL);
6221 result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain);
6223 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6229 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
6235 * Retrieve state from fctx->nsfetch before we destroy it.
6239 dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL);
6240 if (dns_name_equal(&fctx->nsname, domain)) {
6241 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6242 dns_resolver_destroyfetch(&fctx->nsfetch);
6246 &fctx->nsfetch->private->nameservers)) {
6248 &fctx->nsfetch->private->nameservers,
6253 dns_resolver_destroyfetch(&fctx->nsfetch);
6254 n = dns_name_countlabels(&fctx->nsname);
6255 dns_name_getlabelsequence(&fctx->nsname, 1, n - 1,
6256 &fctx->nsname);
6261 result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
6264 resume_dslookup, fctx,
6265 &fctx->nsrrset, NULL,
6266 &fctx->nsfetch);
6268 fctx_done(fctx, result, __LINE__);
6272 fctx->references++;
6285 bucket_empty = fctx_decreference(fctx);
6432 query->fctx->res->mctx);
6453 fetchctx_t *fctx;
6466 fctx = query->fctx;
6468 REQUIRE(VALID_FCTX(fctx));
6474 inc_stats(fctx->res, dns_resstatscounter_responsev4);
6476 inc_stats(fctx->res, dns_resstatscounter_responsev6);
6478 (void)isc_timer_touch(fctx->timer);
6488 if (fctx->res->exiting) {
6493 fctx->timeouts = 0;
6494 fctx->timeout = ISC_FALSE;
6495 fctx->addrinfo = query->addrinfo;
6519 add_bad_edns(fctx, &query->addrinfo->sockaddr);
6547 message = fctx->rmessage;
6586 add_bad_edns(fctx,
6588 inc_stats(fctx->res,
6611 add_bad_edns(fctx, &query->addrinfo->sockaddr);
6612 inc_stats(fctx->res,
6631 log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
6644 result = dns_message_checksig(message, fctx->res->view);
6671 bad_edns(fctx, &query->addrinfo->sockaddr)) {
6675 dns_adb_changeflags(fctx->adb, query->addrinfo,
6687 inc_stats(fctx->res, dns_resstatscounter_truncated);
6714 inc_stats(fctx->res, dns_resstatscounter_nxdomain);
6717 inc_stats(fctx->res, dns_resstatscounter_servfail);
6720 inc_stats(fctx->res, dns_resstatscounter_formerr);
6723 inc_stats(fctx->res, dns_resstatscounter_othererror);
6754 add_bad_edns(fctx, &query->addrinfo->sockaddr);
6755 inc_stats(fctx->res, dns_resstatscounter_edns0fail);
6795 dns_adb_changeflags(fctx->adb, query->addrinfo,
6817 result = same_question(fctx);
6828 if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
6829 is_lame(fctx)) {
6830 inc_stats(fctx->res, dns_resstatscounter_lame);
6831 log_lame(fctx, query->addrinfo);
6832 result = dns_adb_marklame(fctx->adb, query->addrinfo,
6833 &fctx->name, fctx->type,
6834 now + fctx->res->lame_ttl);
6849 dns_view_isdelegationonly(fctx->res->view, &fctx->domain) &&
6850 !dns_name_equal(&fctx->domain, &fctx->name) &&
6851 fix_mustbedelegationornxdomain(message, fctx)) {
6858 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
6859 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
6860 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
6861 dns_rdataclass_format(fctx->res->rdclass, classbuf,
6873 if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0)
6879 fctx->attributes &= ~(FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE);
6896 if (fctx->type == dns_rdatatype_ns &&
6900 result = noanswer_response(fctx, NULL, ISC_TRUE);
6917 result = answer_response(fctx);
6929 result = noanswer_response(fctx, NULL, ISC_FALSE);
6943 fctx->restarts = 0;
6949 fctx->referrals++;
6950 fctx->querysent = 0;
6951 fctx->lamecount = 0;
6952 fctx->neterr = 0;
6953 fctx->badresp = 0;
6954 fctx->adberr = 0;
6978 chase_additional(fctx);
6984 if (WANTCACHE(fctx)) {
6985 result = cache_message(fctx, query->addrinfo, now);
6994 if (WANTNCACHE(fctx)) {
6999 covers = fctx->type;
7004 result = ncache_message(fctx, query->addrinfo, covers, now);
7027 * this fctx.
7029 add_bad(fctx, addrinfo, broken_server, broken_type);
7037 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7041 if (dns_rdatatype_atparent(fctx->type))
7044 name = &fctx->name;
7046 name = &fctx->domain;
7047 result = dns_view_findzonecut(fctx->res->view,
7051 &fctx->nameservers,
7055 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7058 if (!dns_name_issubdomain(fname, &fctx->domain)) {
7064 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7067 dns_name_free(&fctx->domain, fctx->mctx);
7068 dns_name_init(&fctx->domain, NULL);
7069 result = dns_name_dup(fname, fctx->mctx, &fctx->domain);
7071 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7074 fctx->ns_ttl = fctx->nameservers.ttl;
7075 fctx->ns_ttl_ok = ISC_TRUE;
7076 fctx_cancelqueries(fctx, ISC_TRUE);
7077 fctx_cleanupfinds(fctx);
7078 fctx_cleanupaltfinds(fctx);
7079 fctx_cleanupforwaddrs(fctx);
7080 fctx_cleanupaltaddrs(fctx);
7085 fctx_try(fctx, !get_nameservers, ISC_FALSE);
7091 inc_stats(fctx->res, dns_resstatscounter_retry);
7092 result = fctx_query(fctx, addrinfo, options);
7094 fctx_done(fctx, result, __LINE__);
7095 } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
7101 fctx_cancelqueries(fctx, ISC_TRUE);
7106 result = fctx_stopidletimer(fctx);
7108 fctx_done(fctx, result, __LINE__);
7111 add_bad(fctx, addrinfo, result, broken_type);
7112 fctx_cancelqueries(fctx, ISC_TRUE);
7113 fctx_cleanupfinds(fctx);
7114 fctx_cleanupforwaddrs(fctx);
7116 n = dns_name_countlabels(&fctx->name);
7117 dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname);
7121 result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
7124 resume_dslookup, fctx,
7125 &fctx->nsrrset, NULL,
7126 &fctx->nsfetch);
7128 fctx_done(fctx, result, __LINE__);
7130 LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
7131 fctx->references++;
7132 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
7133 result = fctx_stopidletimer(fctx);
7135 fctx_done(fctx, result, __LINE__);
7141 fctx_done(fctx, result, __LINE__);
7661 fetchctx_t *fctx;
7677 for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs);
7678 fctx != NULL;
7679 fctx = ISC_LIST_NEXT(fctx, link))
7680 fctx_shutdown(fctx);
7738 fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
7744 if (fctx->cloned || fctx->state == fetchstate_done ||
7745 ISC_LIST_EMPTY(fctx->events))
7748 if (fctx->type != type || fctx->options != options)
7750 return (dns_name_equal(&fctx->name, name));
7800 fetchctx_t *fctx = NULL;
7849 for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs);
7850 fctx != NULL;
7851 fctx = ISC_LIST_NEXT(fctx, link)) {
7852 if (fctx_match(fctx, name, type, options))
7860 if (fctx != NULL && client != NULL) {
7862 for (fevent = ISC_LIST_HEAD(fctx->events);
7874 INSIST(fctx != NULL);
7876 fctx->spilled = ISC_TRUE;
7877 if (fctx->spilled) {
7883 if (fctx == NULL) {
7885 options, bucketnum, &fctx);
7891 result = fctx_join(fctx, task, client, id, action, arg,
7896 * Launch this fctx.
7898 event = &fctx->control_event;
7901 fctx_start, fctx, NULL,
7909 (void)fctx_unlink(fctx);
7918 fctx_destroy(fctx);
7931 fetchctx_t *fctx;
7937 fctx = fetch->private;
7938 REQUIRE(VALID_FCTX(fctx));
7939 res = fctx->res;
7943 LOCK(&res->buckets[fctx->bucketnum].lock);
7948 * fctx) and send it with result = ISC_R_CANCELED.
7951 if (fctx->state != fetchstate_done) {
7952 for (event = ISC_LIST_HEAD(fctx->events);
7957 ISC_LIST_UNLINK(fctx->events, event, ev_link);
7964 event->ev_sender = fctx;
7969 * The fctx continues running even if no fetches remain;
7973 UNLOCK(&res->buckets[fctx->bucketnum].lock);
7981 fetchctx_t *fctx;
7988 fctx = fetch->private;
7989 REQUIRE(VALID_FCTX(fctx));
7990 res = fctx->res;
7994 bucketnum = fctx->bucketnum;
8002 if (fctx->state != fetchstate_done) {
8003 for (event = ISC_LIST_HEAD(fctx->events);
8011 bucket_empty = fctx_decreference(fctx);
8027 fetchctx_t *fctx;
8032 fctx = fetch->private;
8033 REQUIRE(VALID_FCTX(fctx));
8034 res = fctx->res;
8036 LOCK(&res->buckets[fctx->bucketnum].lock);
8038 INSIST(fctx->exitline >= 0);
8039 if (!fctx->logged || duplicateok) {
8040 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
8048 __FILE__, fctx->exitline, fctx->info,
8049 fctx->duration / 1000000,
8050 fctx->duration % 1000000,
8051 isc_result_totext(fctx->result),
8052 isc_result_totext(fctx->vresult), domainbuf,
8053 fctx->referrals, fctx->restarts,
8054 fctx->querysent, fctx->timeouts, fctx->lamecount,
8055 fctx->neterr, fctx->badresp, fctx->adberr,
8056 fctx->findfail, fctx->valfail);
8057 fctx->logged = ISC_TRUE;
8060 UNLOCK(&res->buckets[fctx->bucketnum].lock);