Lines Matching defs:qctx

92 #define QUERY_ERROR(qctx, r)                  \
94 (qctx)->result = r; \
95 (qctx)->want_restart = false; \
96 (qctx)->line = __LINE__; \
186 #define CCTRACE(l, m) client_trace(qctx->client, l, m)
240 query_addanswer(query_ctx_t *qctx);
243 query_prepare_delegation_response(query_ctx_t *qctx);
252 * Return the hooktable in use with 'qctx', or if there isn't one
256 get_hooktab(query_ctx_t *qctx) {
257 if (qctx == NULL || qctx->view == NULL || qctx->view->hooktable == NULL)
262 return qctx->view->hooktable;
390 query_trace(query_ctx_t *qctx);
394 dns_rdatatype_t qtype, query_ctx_t *qctx);
397 qctx_prepare_buffers(query_ctx_t *qctx, isc_buffer_t *buffer);
400 qctx_freedata(query_ctx_t *qctx);
403 qctx_destroy(query_ctx_t *qctx);
409 query_lookup(query_ctx_t *qctx);
419 query_resume(query_ctx_t *qctx);
422 query_checkrrl(query_ctx_t *qctx, isc_result_t result);
425 query_checkrpz(query_ctx_t *qctx, isc_result_t result);
428 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname);
431 query_gotanswer(query_ctx_t *qctx, isc_result_t result);
434 query_addnoqnameproof(query_ctx_t *qctx);
437 query_respond_any(query_ctx_t *qctx);
440 query_respond(query_ctx_t *qctx);
443 query_dns64(query_ctx_t *qctx);
446 query_filter64(query_ctx_t *qctx);
449 query_notfound(query_ctx_t *qctx);
452 query_zone_delegation(query_ctx_t *qctx);
455 query_delegation(query_ctx_t *qctx);
458 query_delegation_recurse(query_ctx_t *qctx);
461 query_addds(query_ctx_t *qctx);
464 query_nodata(query_ctx_t *qctx, isc_result_t result);
467 query_sign_nodata(query_ctx_t *qctx);
470 query_addnxrrsetnsec(query_ctx_t *qctx);
473 query_nxdomain(query_ctx_t *qctx, isc_result_t result);
476 query_redirect(query_ctx_t *qctx, isc_result_t result);
479 query_ncache(query_ctx_t *qctx, isc_result_t result);
482 query_coveringnsec(query_ctx_t *qctx);
485 query_zerottl_refetch(query_ctx_t *qctx);
488 query_cname(query_ctx_t *qctx);
491 query_dname(query_ctx_t *qctx);
494 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl);
497 query_prepresponse(query_ctx_t *qctx);
500 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl,
504 query_addns(query_ctx_t *qctx);
507 query_addbestns(query_ctx_t *qctx);
510 query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata);
513 query_addauth(query_ctx_t *qctx);
1663 * For query context 'qctx', try finding authoritative additional data for
1683 query_additionalauth(query_ctx_t *qctx, const dns_name_t *name,
1687 ns_client_t *client = qctx->client;
1716 qctx->view->minimalresponses == dns_minimal_no &&
1756 query_ctx_t *qctx = arg;
1757 ns_client_t *client = qctx->client;
1813 if (qctx->view->minimalresponses == dns_minimal_yes &&
1822 result = query_additionalauth(qctx, name, type, &db, &node, fname,
1831 if (!qctx->view->recursion) {
1858 dns_cache_updatestats(qctx->view->cache, result);
2147 trdataset, fname, query_additional_cb, qctx);
2189 query_setorder(query_ctx_t *qctx, dns_name_t *name, dns_rdataset_t *rdataset) {
2190 ns_client_t *client = qctx->client;
2208 query_additional(query_ctx_t *qctx, dns_name_t *name,
2210 ns_client_t *client = qctx->client;
2232 result = dns_db_addglue(qctx->db, dbversion->version, rdataset,
2245 qctx);
2250 query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
2254 ns_client_t *client = qctx->client;
2325 query_setorder(qctx, mname, rdataset);
2326 query_additional(qctx, mname, rdataset);
2626 query_ctx_t qctx;
2670 qctx_init(client, NULL, 0, &qctx);
2673 dns_clientinfo_init(&ci, qctx.client, NULL);
2674 if (HAVEECS(qctx.client)) {
2675 dns_clientinfo_setecs(&ci, &qctx.client->ecs);
2678 result = qctx_prepare_buffers(&qctx, &buffer);
2683 dboptions = qctx.client->query.dboptions;
2687 dns_db_attach(qctx.client->view->cachedb, &db);
2688 (void)dns_db_findext(db, qctx.client->query.qname, NULL,
2689 qctx.client->query.qtype, dboptions,
2690 qctx.client->now, &qctx.node, qctx.fname,
2691 &cm, &ci, qctx.rdataset, qctx.sigrdataset);
2692 if (qctx.node != NULL) {
2693 dns_db_detachnode(db, &qctx.node);
2698 qctx_freedata(&qctx);
2699 qctx_destroy(&qctx);
5405 * Initialize query context 'qctx'. Run by query_setup() when
5410 * when leaving the scope or freeing the qctx.
5414 dns_rdatatype_t qtype, query_ctx_t *qctx) {
5415 REQUIRE(qctx != NULL);
5418 memset(qctx, 0, sizeof(*qctx));
5421 qctx->client = client;
5423 dns_view_attach(client->view, &qctx->view);
5428 qctx->fresp = *frespp;
5431 qctx->fresp = NULL;
5433 qctx->qtype = qctx->type = qtype;
5434 qctx->result = ISC_R_SUCCESS;
5435 qctx->findcoveringnsec = qctx->view->synthfromdnssec;
5440 if (qctx->qtype == dns_rdatatype_rrsig ||
5441 qctx->qtype == dns_rdatatype_sig)
5443 qctx->type = dns_rdatatype_any;
5446 CALL_HOOK_NORETURN(NS_QUERY_QCTX_INITIALIZED, qctx);
5450 * Clean up and disassociate the rdataset and node pointers in qctx.
5453 qctx_clean(query_ctx_t *qctx) {
5454 if (qctx->rdataset != NULL && dns_rdataset_isassociated(qctx->rdataset))
5456 dns_rdataset_disassociate(qctx->rdataset);
5458 if (qctx->sigrdataset != NULL &&
5459 dns_rdataset_isassociated(qctx->sigrdataset))
5461 dns_rdataset_disassociate(qctx->sigrdataset);
5463 if (qctx->db != NULL && qctx->node != NULL) {
5464 dns_db_detachnode(qctx->db, &qctx->node);
5469 * Free any allocated memory associated with qctx.
5472 qctx_freedata(query_ctx_t *qctx) {
5473 if (qctx->rdataset != NULL) {
5474 ns_client_putrdataset(qctx->client, &qctx->rdataset);
5477 if (qctx->sigrdataset != NULL) {
5478 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
5481 if (qctx->fname != NULL) {
5482 ns_client_releasename(qctx->client, &qctx->fname);
5485 if (qctx->db != NULL) {
5486 INSIST(qctx->node == NULL);
5487 dns_db_detach(&qctx->db);
5490 if (qctx->zone != NULL) {
5491 dns_zone_detach(&qctx->zone);
5494 if (qctx->zdb != NULL) {
5495 ns_client_putrdataset(qctx->client, &qctx->zsigrdataset);
5496 ns_client_putrdataset(qctx->client, &qctx->zrdataset);
5497 ns_client_releasename(qctx->client, &qctx->zfname);
5498 dns_db_detachnode(qctx->zdb, &qctx->znode);
5499 dns_db_detach(&qctx->zdb);
5500 qctx->zversion = NULL;
5503 if (qctx->fresp != NULL) {
5504 free_fresp(qctx->client, &qctx->fresp);
5509 qctx_destroy(query_ctx_t *qctx) {
5510 CALL_HOOK_NORETURN(NS_QUERY_QCTX_DESTROYED, qctx);
5512 dns_view_detach(&qctx->view);
5525 * "save" qctx data from 'src' to 'tgt'.
5566 query_trace(query_ctx_t *qctx) {
5571 if (qctx->client->query.origqname != NULL) {
5572 dns_name_format(qctx->client->query.origqname, qbuf,
5581 qctx->client->attributes, qctx->client->query.attributes,
5582 qctx->client->query.restarts, qbuf,
5583 (int)qctx->client->query.timerset,
5584 (int)qctx->client->query.authdbset,
5585 (int)qctx->client->query.isreferral);
5588 UNUSED(qctx);
5606 query_ctx_t qctx;
5608 qctx_init(client, NULL, qtype, &qctx);
5609 query_trace(&qctx);
5611 CALL_HOOK(NS_QUERY_SETUP, &qctx);
5616 result = ns__query_sfcache(&qctx);
5621 (void)ns__query_start(&qctx);
5624 qctx_destroy(&qctx);
5628 get_root_key_sentinel_id(query_ctx_t *qctx, const char *ndata) {
5642 qctx->client->query.root_key_sentinel_keyid = v;
5653 root_key_sentinel_detect(query_ctx_t *qctx) {
5654 const char *ndata = (const char *)qctx->client->query.qname->ndata;
5656 if (qctx->client->query.qname->length > 30 && ndata[0] == 29 &&
5659 if (!get_root_key_sentinel_id(qctx, ndata + 25)) {
5662 qctx->client->query.root_key_sentinel_is_ta = true;
5667 qctx->findcoveringnsec = false;
5668 ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
5671 } else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 &&
5674 if (!get_root_key_sentinel_id(qctx, ndata + 26)) {
5677 qctx->client->query.root_key_sentinel_not_ta = true;
5682 qctx->findcoveringnsec = false;
5683 ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
5697 ns__query_start(query_ctx_t *qctx) {
5700 qctx->want_restart = false;
5701 qctx->authoritative = false;
5702 qctx->version = NULL;
5703 qctx->zversion = NULL;
5704 qctx->need_wildcardproof = false;
5705 qctx->rpz = false;
5707 CALL_HOOK(NS_QUERY_START_BEGIN, qctx);
5714 if (!TCP(qctx->client) &&
5715 (BADCOOKIE(qctx->client) ||
5716 (qctx->view->requireservercookie && WANTCOOKIE(qctx->client) &&
5717 !HAVECOOKIE(qctx->client))))
5719 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
5720 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
5721 qctx->client->message->rcode = dns_rcode_badcookie;
5722 return ns_query_done(qctx);
5725 if (qctx->view->checknames &&
5726 !dns_rdata_checkowner(qctx->client->query.qname,
5727 qctx->client->message->rdclass, qctx->qtype,
5734 dns_name_format(qctx->client->query.qname, namebuf,
5736 dns_rdatatype_format(qctx->qtype, typebuf, sizeof(typebuf));
5737 dns_rdataclass_format(qctx->client->message->rdclass, classbuf,
5739 ns_client_log(qctx->client, DNS_LOGCATEGORY_SECURITY,
5743 QUERY_ERROR(qctx, DNS_R_REFUSED);
5744 return ns_query_done(qctx);
5750 if (qctx->view->root_key_sentinel &&
5751 qctx->client->query.restarts == 0 &&
5752 (qctx->qtype == dns_rdatatype_a ||
5753 qctx->qtype == dns_rdatatype_aaaa) &&
5754 (qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0)
5756 root_key_sentinel_detect(qctx);
5763 qctx->options = (dns_getdb_options_t){ .nolog = qctx->options.nolog };
5764 if (dns_rdatatype_atparent(qctx->qtype) &&
5765 !dns_name_equal(qctx->client->query.qname, dns_rootname))
5773 qctx->options.noexact = true;
5776 result = query_getdb(qctx->client, qctx->client->query.qname,
5777 qctx->qtype, qctx->options, &qctx->zone, &qctx->db,
5778 &qctx->version, &qctx->is_zone);
5779 if ((result != ISC_R_SUCCESS || !qctx->is_zone) &&
5780 qctx->qtype == dns_rdatatype_ds && !RECURSIONOK(qctx->client) &&
5781 qctx->options.noexact)
5796 qctx->client, qctx->client->query.qname, qctx->qtype,
5803 qctx->options.noexact = false;
5804 ns_client_putrdataset(qctx->client, &qctx->rdataset);
5805 if (qctx->db != NULL) {
5806 dns_db_detach(&qctx->db);
5808 if (qctx->zone != NULL) {
5809 dns_zone_detach(&qctx->zone);
5811 qctx->version = NULL;
5812 RESTORE(qctx->version, tversion);
5813 RESTORE(qctx->db, tdb);
5814 RESTORE(qctx->zone, tzone);
5815 qctx->is_zone = true;
5837 if (WANTRECURSION(qctx->client)) {
5838 inc_stats(qctx->client,
5841 inc_stats(qctx->client,
5844 if (!PARTIALANSWER(qctx->client)) {
5845 QUERY_ERROR(qctx, DNS_R_REFUSED);
5850 QUERY_ERROR(qctx, result);
5852 return ns_query_done(qctx);
5860 qctx->is_staticstub_zone = false;
5861 if (qctx->is_zone) {
5862 qctx->authoritative = true;
5863 if (qctx->zone != NULL) {
5864 if (dns_zone_gettype(qctx->zone) == dns_zone_mirror) {
5865 qctx->authoritative = false;
5867 if (dns_zone_gettype(qctx->zone) == dns_zone_staticstub)
5869 qctx->is_staticstub_zone = true;
5878 if (qctx->fresp == NULL && qctx->client->query.restarts == 0) {
5879 if (qctx->is_zone) {
5880 if (qctx->zone != NULL) {
5885 dns_zone_attach(qctx->zone,
5886 &qctx->client->query.authzone);
5888 dns_db_attach(qctx->db, &qctx->client->query.authdb);
5890 qctx->client->query.authdbset = true;
5893 if (TCP(qctx->client)) {
5894 inc_stats(qctx->client, ns_statscounter_tcp);
5896 inc_stats(qctx->client, ns_statscounter_udp);
5900 if (!qctx->is_zone && qctx->view->staleanswerclienttimeout == 0 &&
5901 dns_view_staleanswerenabled(qctx->view))
5908 qctx->options.stalefirst = true;
5911 result = query_lookup(qctx);
5918 qctx->options.stalefirst = false;
5926 query_ctx_t *qctx = arg;
5927 ns_client_t *client = qctx->client;
5932 ns__query_start(qctx);
5934 qctx_clean(qctx);
5935 qctx_freedata(qctx);
5936 qctx_destroy(qctx);
5937 isc_mem_put(client->manager->mctx, qctx, sizeof(*qctx));
5942 * Allocate buffers in 'qctx' used to store query results.
5945 * doesn't expire while 'qctx' is in use.
5948 qctx_prepare_buffers(query_ctx_t *qctx, isc_buffer_t *buffer) {
5949 REQUIRE(qctx != NULL);
5950 REQUIRE(qctx->client != NULL);
5953 qctx->dbuf = ns_client_getnamebuf(qctx->client);
5954 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, buffer);
5955 qctx->rdataset = ns_client_newrdataset(qctx->client);
5957 if ((WANTDNSSEC(qctx->client) || qctx->findcoveringnsec) &&
5958 (!qctx->is_zone || dns_db_issecure(qctx->db)))
5960 qctx->sigrdataset = ns_client_newrdataset(qctx->client);
5993 query_lookup(query_ctx_t *qctx) {
6012 CALL_HOOK(NS_QUERY_LOOKUP_BEGIN, qctx);
6015 dns_clientinfo_init(&ci, qctx->client, NULL);
6016 if (HAVEECS(qctx->client)) {
6017 dns_clientinfo_setecs(&ci, &qctx->client->ecs);
6023 result = qctx_prepare_buffers(qctx, &buffer);
6025 QUERY_ERROR(qctx, result);
6026 return ns_query_done(qctx);
6032 if (qctx->dns64 && qctx->rpz) {
6033 rpzqname = qctx->client->query.rpz_st->p_name;
6035 rpzqname = qctx->client->query.qname;
6038 if (qctx->options.stalefirst) {
6045 qctx->client->query.dboptions |= DNS_DBFIND_STALETIMEOUT;
6048 dboptions = qctx->client->query.dboptions;
6049 if (!qctx->is_zone && qctx->findcoveringnsec &&
6050 (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname)))
6055 (void)dns_db_getservestalerefresh(qctx->client->view->cachedb,
6058 dns_view_staleanswerenabled(qctx->client->view))
6063 result = dns_db_findext(qctx->db, rpzqname, qctx->version, qctx->type,
6064 dboptions, qctx->client->now, &qctx->node,
6065 qctx->fname, &cm, &ci, qctx->rdataset,
6066 qctx->sigrdataset);
6071 if (qctx->dns64 && qctx->rpz) {
6072 dns_name_copy(qctx->client->query.qname, qctx->fname);
6073 if (qctx->sigrdataset != NULL &&
6074 dns_rdataset_isassociated(qctx->sigrdataset))
6076 dns_rdataset_disassociate(qctx->sigrdataset);
6080 if (!qctx->is_zone) {
6081 dns_cache_updatestats(qctx->view->cache, result);
6097 stale_refresh_window = (STALE_WINDOW(qctx->rdataset) &&
6109 if (dns_rdataset_isassociated(qctx->rdataset) &&
6110 dns_rdataset_count(qctx->rdataset) > 0 && !STALE(qctx->rdataset))
6117 dns_name_format(qctx->client->query.qname, namebuf,
6119 dns_rdatatype_format(qctx->qtype, typebuf, sizeof(typebuf));
6121 inc_stats(qctx->client, ns_statscounter_trystale);
6123 if (dns_rdataset_isassociated(qctx->rdataset) &&
6124 dns_rdataset_count(qctx->rdataset) > 0 &&
6125 STALE(qctx->rdataset))
6135 qctx->rdataset->ttl = qctx->view->staleanswerttl;
6136 inc_stats(qctx->client, ns_statscounter_usedstale);
6150 ns_client_extendederror(qctx->client, ede,
6157 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
6158 return ns_query_done(qctx);
6175 qctx->client, ede,
6182 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
6183 return ns_query_done(qctx);
6186 if (qctx->options.stalefirst) {
6192 qctx_clean(qctx);
6193 qctx_freedata(qctx);
6194 dns_db_attach(qctx->client->view->cachedb,
6195 &qctx->db);
6196 qctx->client->query.dboptions &=
6198 qctx->options.stalefirst = false;
6199 if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL)
6203 qctx->client));
6205 return query_lookup(qctx);
6218 qctx->refresh_rrset = STALE(qctx->rdataset);
6221 qctx->client, ede,
6237 qctx->client->query.attributes |= NS_QUERYATTR_STALEOK;
6238 qctx->rdataset->attributes |= DNS_RDATASETATTR_STALE_ADDED;
6241 result = query_gotanswer(qctx, result);
6317 query_ctx_t qctx;
6370 * Initialize a new qctx and use it to either resume from
6372 * ownership of resp to the new qctx in the process.
6374 qctx_init(client, &resp, 0, &qctx);
6379 * free the event and other resources held by qctx, but
6383 qctx_freedata(&qctx);
6395 qctx.detach_client = true;
6396 qctx_destroy(&qctx);
6401 query_trace(&qctx);
6403 result = query_resume(&qctx);
6418 qctx_destroy(&qctx);
6613 query_resume(query_ctx_t *qctx) {
6625 CALL_HOOK(NS_QUERY_RESUME_BEGIN, qctx);
6627 qctx->want_restart = false;
6629 qctx->rpz_st = qctx->client->query.rpz_st;
6630 if (qctx->rpz_st != NULL &&
6631 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0)
6638 if (qctx->rpz_st->r_name != NULL) {
6639 dns_name_format(qctx->rpz_st->r_name, qbuf,
6644 if (qctx->rpz_st->p_name != NULL) {
6645 dns_name_format(qctx->rpz_st->p_name, pbuf,
6648 if (qctx->rpz_st->fname != NULL) {
6649 dns_name_format(qctx->rpz_st->fname, fbuf,
6654 "rpz rname:%s, pname:%s, qctx->fname:%s", qbuf,
6660 qctx->is_zone = qctx->rpz_st->q.is_zone;
6661 qctx->authoritative = qctx->rpz_st->q.authoritative;
6662 RESTORE(qctx->zone, qctx->rpz_st->q.zone);
6663 RESTORE(qctx->node, qctx->rpz_st->q.node);
6664 RESTORE(qctx->db, qctx->rpz_st->q.db);
6665 RESTORE(qctx->rdataset, qctx->rpz_st->q.rdataset);
6666 RESTORE(qctx->sigrdataset, qctx->rpz_st->q.sigrdataset);
6667 qctx->qtype = qctx->rpz_st->q.qtype;
6669 if (qctx->fresp->node != NULL) {
6670 dns_db_detachnode(qctx->fresp->db, &qctx->fresp->node);
6672 SAVE(qctx->rpz_st->r.db, qctx->fresp->db);
6673 qctx->rpz_st->r.r_type = qctx->fresp->qtype;
6674 SAVE(qctx->rpz_st->r.r_rdataset, qctx->fresp->rdataset);
6675 ns_client_putrdataset(qctx->client, &qctx->fresp->sigrdataset);
6676 } else if (REDIRECT(qctx->client)) {
6682 dns_name_format(qctx->client->query.redirect.fname, qbuf,
6684 dns_rdatatype_format(qctx->client->query.redirect.qtype, tbuf,
6687 "redirect qctx->fname:%s, qtype:%s, auth:%d", qbuf,
6688 tbuf, qctx->client->query.redirect.authoritative);
6691 qctx->qtype = qctx->client->query.redirect.qtype;
6692 INSIST(qctx->client->query.redirect.rdataset != NULL);
6693 RESTORE(qctx->rdataset, qctx->client->query.redirect.rdataset);
6694 RESTORE(qctx->sigrdataset,
6695 qctx->client->query.redirect.sigrdataset);
6696 RESTORE(qctx->db, qctx->client->query.redirect.db);
6697 RESTORE(qctx->node, qctx->client->query.redirect.node);
6698 RESTORE(qctx->zone, qctx->client->query.redirect.zone);
6699 qctx->authoritative =
6700 qctx->client->query.redirect.authoritative;
6705 ns_client_putrdataset(qctx->client, &qctx->fresp->rdataset);
6706 ns_client_putrdataset(qctx->client, &qctx->fresp->sigrdataset);
6707 if (qctx->fresp->node != NULL) {
6708 dns_db_detachnode(qctx->fresp->db, &qctx->fresp->node);
6710 if (qctx->fresp->db != NULL) {
6711 dns_db_detach(&qctx->fresp->db);
6715 qctx->authoritative = false;
6717 qctx->qtype = qctx->fresp->qtype;
6718 SAVE(qctx->db, qctx->fresp->db);
6719 SAVE(qctx->node, qctx->fresp->node);
6720 SAVE(qctx->rdataset, qctx->fresp->rdataset);
6721 SAVE(qctx->sigrdataset, qctx->fresp->sigrdataset);
6723 INSIST(qctx->rdataset != NULL);
6725 if (qctx->qtype == dns_rdatatype_rrsig ||
6726 qctx->qtype == dns_rdatatype_sig)
6728 qctx->type = dns_rdatatype_any;
6730 qctx->type = qctx->qtype;
6733 CALL_HOOK(NS_QUERY_RESUME_RESTORED, qctx);
6735 if (DNS64(qctx->client)) {
6736 qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64;
6737 qctx->dns64 = true;
6740 if (DNS64EXCLUDE(qctx->client)) {
6741 qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
6742 qctx->dns64_exclude = true;
6745 if (qctx->rpz_st != NULL &&
6746 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0)
6751 if (qctx->rpz_st->rpz_ver != qctx->view->rpzs->rpz_ver) {
6752 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
6757 qctx->view->rpzs->rpz_ver,
6758 qctx->rpz_st->rpz_ver);
6759 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
6760 return ns_query_done(qctx);
6767 qctx->dbuf = ns_client_getnamebuf(qctx->client);
6768 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
6770 if (qctx->rpz_st != NULL &&
6771 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0)
6773 tname = qctx->rpz_st->fname;
6774 } else if (REDIRECT(qctx->client)) {
6775 tname = qctx->client->query.redirect.fname;
6777 tname = qctx->fresp->foundname;
6780 dns_name_copy(tname, qctx->fname);
6782 if (qctx->rpz_st != NULL &&
6783 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0)
6785 qctx->rpz_st->r.r_result = qctx->fresp->result;
6786 result = qctx->rpz_st->q.result;
6787 free_fresp(qctx->client, &qctx->fresp);
6788 } else if (REDIRECT(qctx->client)) {
6789 result = qctx->client->query.redirect.result;
6791 result = qctx->fresp->result;
6794 qctx->resuming = true;
6796 return query_gotanswer(qctx, result);
6807 query_ctx_t *qctx = rev->saved_qctx;
6847 * in qctx. We need to do it here to prevent leak.
6849 qctx_clean(qctx);
6850 qctx_freedata(qctx);
6857 qctx->detach_client = true;
6861 query_setup(client, qctx->qtype);
6864 (void)ns__query_start(qctx);
6867 (void)query_lookup(qctx);
6871 (void)query_resume(qctx);
6874 (void)query_gotanswer(qctx, rev->origresult);
6877 (void)query_respond_any(qctx);
6880 (void)query_addanswer(qctx);
6883 (void)query_notfound(qctx);
6886 (void)query_prepare_delegation_response(qctx);
6889 (void)query_zone_delegation(qctx);
6892 (void)query_delegation(qctx);
6895 (void)query_delegation_recurse(qctx);
6898 (void)query_nodata(qctx, rev->origresult);
6901 (void)query_nxdomain(qctx, rev->origresult);
6904 (void)query_ncache(qctx, rev->origresult);
6907 (void)query_cname(qctx);
6910 (void)query_dname(qctx);
6913 (void)query_respond(qctx);
6916 (void)query_prepresponse(qctx);
6920 (void)ns_query_done(qctx);
6934 qctx_destroy(qctx);
6935 isc_mem_put(client->manager->mctx, qctx, sizeof(*qctx));
6939 ns_query_hookasync(query_ctx_t *qctx, ns_query_starthookasync_t runasync,
6942 ns_client_t *client = qctx->client;
6957 qctx_save(qctx, saved_qctx);
7002 qctx->detach_client = true;
7014 ns__query_sfcache(query_ctx_t *qctx) {
7021 if (!RECURSIONOK(qctx->client)) {
7027 if (qctx->client->manager->sctx->fuzztype == isc_fuzz_resolver) {
7033 qctx->view->failcache, qctx->client->query.qname,
7034 qctx->qtype, &flags,
7035 isc_time_seconds(&qctx->client->tnow));
7043 ((qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0))
7049 dns_name_format(qctx->client->query.qname, namebuf,
7051 dns_rdatatype_format(qctx->qtype, typebuf,
7053 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
7062 qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
7063 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
7064 return ns_query_done(qctx);
7071 query_trace_rrldrop(query_ctx_t *qctx,
7079 isc_netaddr_fromsockaddr(&peer, &qctx->client->peeraddr);
7084 dns_name_format(qctx->client->query.qname, qnamebuf, sizeof(qnamebuf));
7085 dns_name_format(qctx->fname, fnamebuf, sizeof(fnamebuf));
7093 query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
7111 qctx->client, DNS_LOGCATEGORY_RRL, NS_LOGMODULE_QUERY,
7116 qctx->client->view->rrl, HAVECOOKIE(qctx->client),
7117 isc_result_toid(result), qctx->fname,
7118 qctx->fname != NULL ? dns_name_isabsolute(qctx->fname) : 0,
7119 qctx->is_zone, RECURSIONOK(qctx->client),
7120 qctx->client->query.rpz_st,
7121 qctx->client->query.rpz_st != NULL
7122 ? ((qctx->client->query.rpz_st->state &
7125 (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) !=
7128 if (qctx->view->rrl != NULL && !HAVECOOKIE(qctx->client) &&
7129 ((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) ||
7130 (result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) &&
7131 !(result == DNS_R_DELEGATION && !qctx->is_zone &&
7132 RECURSIONOK(qctx->client)) &&
7133 (qctx->client->query.rpz_st == NULL ||
7134 (qctx->client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
7135 (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0)
7145 qctx->client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
7148 constname = qctx->fname;
7153 if (qctx->db != NULL) {
7154 constname = dns_db_origin(qctx->db);
7158 qctx->rdataset != NULL &&
7159 dns_rdataset_isassociated(qctx->rdataset) &&
7160 (qctx->rdataset->attributes &
7168 for (nc_result = dns_rdataset_first(qctx->rdataset);
7170 nc_result = dns_rdataset_next(qctx->rdataset))
7172 dns_ncache_current(qctx->rdataset,
7201 qctx->view, qctx->zone, &qctx->client->peeraddr,
7202 TCP(qctx->client), qctx->client->message->rdclass,
7203 qctx->qtype, constname, resp_result, qctx->client->now,
7217 ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL,
7226 query_trace_rrldrop(qctx, rrl_result);
7228 if (!qctx->view->rrl->log_only) {
7234 inc_stats(qctx->client,
7236 QUERY_ERROR(qctx, DNS_R_DROP);
7242 inc_stats(qctx->client,
7244 if (WANTCOOKIE(qctx->client)) {
7245 qctx->client->message->flags &=
7247 qctx->client->message->flags &=
7249 qctx->client->message->rcode =
7252 qctx->client->message->flags |=
7257 qctx->client->message
7275 query_checkrpz(query_ctx_t *qctx, isc_result_t result) {
7280 rresult = rpz_rewrite(qctx->client, qctx->qtype, result, qctx->resuming,
7281 qctx->rdataset, qctx->sigrdataset);
7282 qctx->rpz_st = qctx->client->query.rpz_st;
7294 INSIST(!RECURSING(qctx->client));
7295 qctx->rpz_st->q.qtype = qctx->qtype;
7296 qctx->rpz_st->q.is_zone = qctx->is_zone;
7297 qctx->rpz_st->q.authoritative = qctx->authoritative;
7298 SAVE(qctx->rpz_st->q.zone, qctx->zone);
7299 SAVE(qctx->rpz_st->q.db, qctx->db);
7300 SAVE(qctx->rpz_st->q.node, qctx->node);
7301 SAVE(qctx->rpz_st->q.rdataset, qctx->rdataset);
7302 SAVE(qctx->rpz_st->q.sigrdataset, qctx->sigrdataset);
7303 dns_name_copy(qctx->fname, qctx->rpz_st->fname);
7304 qctx->rpz_st->q.result = result;
7305 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
7308 QUERY_ERROR(qctx, rresult);
7312 if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS) {
7313 qctx->rpz_st->state |= DNS_RPZ_REWRITTEN;
7316 if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS &&
7317 qctx->rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU &&
7318 (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY ||
7319 !TCP(qctx->client)) &&
7320 qctx->rpz_st->m.policy != DNS_RPZ_POLICY_ERROR)
7328 dns_name_copy(qctx->client->query.qname, qctx->fname);
7329 rpz_clean(&qctx->zone, &qctx->db, &qctx->node, NULL);
7330 if (qctx->rpz_st->m.rdataset != NULL) {
7331 ns_client_putrdataset(qctx->client, &qctx->rdataset);
7332 RESTORE(qctx->rdataset, qctx->rpz_st->m.rdataset);
7334 qctx_clean(qctx);
7336 qctx->version = NULL;
7338 RESTORE(qctx->node, qctx->rpz_st->m.node);
7339 RESTORE(qctx->db, qctx->rpz_st->m.db);
7340 RESTORE(qctx->version, qctx->rpz_st->m.version);
7341 RESTORE(qctx->zone, qctx->rpz_st->m.zone);
7346 if (qctx->rpz_st->m.rpz->addsoa) {
7347 rresult = query_addsoa(qctx, UINT32_MAX,
7350 QUERY_ERROR(qctx, result);
7355 switch (qctx->rpz_st->m.policy) {
7357 qctx->client->message->flags |= DNS_MESSAGEFLAG_TC;
7361 qctx->client->message->rcode =
7364 rpz_log_rewrite(qctx->client, false,
7365 qctx->rpz_st->m.policy,
7366 qctx->rpz_st->m.type, qctx->zone,
7367 qctx->rpz_st->p_name, NULL,
7368 qctx->rpz_st->m.rpz->num);
7371 QUERY_ERROR(qctx, DNS_R_DROP);
7372 rpz_log_rewrite(qctx->client, false,
7373 qctx->rpz_st->m.policy,
7374 qctx->rpz_st->m.type, qctx->zone,
7375 qctx->rpz_st->p_name, NULL,
7376 qctx->rpz_st->m.rpz->num);
7380 qctx->nxrewrite = true;
7381 qctx->rpz = true;
7384 qctx->nxrewrite = true;
7388 qctx->rpz = true;
7391 result = qctx->rpz_st->m.result;
7392 if (qctx->qtype == dns_rdatatype_any &&
7400 if (dns_rdataset_isassociated(qctx->rdataset)) {
7402 qctx->rdataset);
7408 qctx->rdataset->ttl =
7409 ISC_MIN(qctx->rdataset->ttl,
7410 qctx->rpz_st->m.ttl);
7412 qctx->rpz = true;
7417 result = dns_rdataset_first(qctx->rdataset);
7419 dns_rdataset_current(qctx->rdataset, &rdata);
7423 result = query_rpzcname(qctx, &cname.cname);
7427 qctx->fname = NULL;
7428 qctx->want_restart = true;
7436 result = query_rpzcname(qctx,
7437 &qctx->rpz_st->m.rpz->cname);
7441 qctx->fname = NULL;
7442 qctx->want_restart = true;
7448 if (qctx->rpz_st->m.rpz->ede != 0 &&
7449 qctx->rpz_st->m.rpz->ede != UINT16_MAX)
7451 ns_client_extendederror(qctx->client,
7452 qctx->rpz_st->m.rpz->ede, NULL);
7459 qctx->client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
7461 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
7462 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
7463 qctx->rpz_st->q.is_zone = qctx->is_zone;
7464 qctx->is_zone = true;
7465 rpz_log_rewrite(qctx->client, false, qctx->rpz_st->m.policy,
7466 qctx->rpz_st->m.type, qctx->zone,
7467 qctx->rpz_st->p_name, NULL,
7468 qctx->rpz_st->m.rpz->num);
7481 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname) {
7487 REQUIRE(qctx != NULL && qctx->client != NULL);
7489 client = qctx->client;
7503 qctx->fname, NULL);
7510 dns_name_copy(cname, qctx->fname);
7513 ns_client_keepname(client, qctx->fname, qctx->dbuf);
7514 query_addcname(qctx, dns_trust_authanswer, qctx->rpz_st->m.ttl);
7516 rpz_log_rewrite(client, false, qctx->rpz_st->m.policy,
7517 qctx->rpz_st->m.type, qctx->rpz_st->m.zone,
7518 qctx->rpz_st->p_name, qctx->fname,
7519 qctx->rpz_st->m.rpz->num);
7521 ns_client_qnamereplace(client, qctx->fname);
7535 * with a key id that matches qctx->client->query.root_key_sentinel_keyid.
7540 has_ta(query_ctx_t *qctx) {
7544 dns_keytag_t sentinel = qctx->client->query.root_key_sentinel_keyid;
7547 result = dns_view_getsecroots(qctx->view, &keytable);
7597 root_key_sentinel_return_servfail(query_ctx_t *qctx, isc_result_t result) {
7601 if (!qctx->client->query.root_key_sentinel_is_ta &&
7602 !qctx->client->query.root_key_sentinel_not_ta)
7625 if (!qctx->is_zone && qctx->rdataset->trust == dns_trust_secure &&
7626 ((qctx->client->query.root_key_sentinel_is_ta && !has_ta(qctx)) ||
7627 (qctx->client->query.root_key_sentinel_not_ta && has_ta(qctx))))
7636 qctx->client->query.root_key_sentinel_is_ta = false;
7637 qctx->client->query.root_key_sentinel_not_ta = false;
7643 * If serving stale answers is allowed, set up 'qctx' to look for one and
7647 query_usestale(query_ctx_t *qctx, isc_result_t result) {
7648 if ((qctx->client->query.dboptions & DNS_DBFIND_STALEOK) != 0) {
7664 qctx_clean(qctx);
7665 qctx_freedata(qctx);
7667 if (dns_view_staleanswerenabled(qctx->client->view)) {
7669 ret = query_getdb(qctx->client, qctx->client->query.qname,
7670 qctx->client->query.qtype, qctx->options,
7671 &qctx->zone, &qctx->db, &qctx->version,
7672 &qctx->is_zone);
7681 qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
7682 if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL) {
7684 &FETCH_RECTYPE_NORMAL(qctx->client));
7691 if (qctx->resuming && result == ISC_R_TIMEDOUT) {
7692 qctx->client->query.dboptions |= DNS_DBFIND_STALESTART;
7706 query_gotanswer(query_ctx_t *qctx, isc_result_t result) {
7711 CALL_HOOK(NS_QUERY_GOT_ANSWER_BEGIN, qctx);
7713 if (query_checkrrl(qctx, result) != ISC_R_SUCCESS) {
7714 return ns_query_done(qctx);
7717 if (!dns_name_equal(qctx->client->query.qname, dns_rootname)) {
7718 result = query_checkrpz(qctx, result);
7725 if (RECURSING(qctx->client) && result == DNS_R_DISALLOWED) {
7736 return ns_query_done(qctx);
7745 if (root_key_sentinel_return_servfail(qctx, result)) {
7749 qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
7750 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
7751 return ns_query_done(qctx);
7756 return query_prepresponse(qctx);
7760 INSIST(qctx->is_zone);
7761 qctx->authoritative = false;
7762 return query_prepresponse(qctx);
7765 return query_notfound(qctx);
7768 return query_delegation(qctx);
7772 return query_nodata(qctx, result);
7776 return query_nxdomain(qctx, result);
7779 return query_coveringnsec(qctx);
7782 result = query_redirect(qctx, result);
7786 return query_ncache(qctx, DNS_R_NCACHENXDOMAIN);
7789 return query_ncache(qctx, DNS_R_NCACHENXRRSET);
7792 return query_cname(qctx);
7795 return query_dname(qctx);
7805 if (query_usestale(qctx, result)) {
7808 * set up 'qctx' for looking up a stale response.
7810 return query_lookup(qctx);
7817 qctx->client->rcode_override = dns_rcode_servfail;
7819 QUERY_ERROR(qctx, result);
7820 return ns_query_done(qctx);
7828 query_addnoqnameproof(query_ctx_t *qctx) {
7829 ns_client_t *client = qctx->client;
7837 if (qctx->noqname == NULL) {
7846 result = dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig);
7849 query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
7852 if ((qctx->noqname->attributes & DNS_RDATASETATTR_CLOSEST) == 0) {
7873 result = dns_rdataset_getclosest(qctx->noqname, fname, neg, negsig);
7876 query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
7895 query_respond_any(query_ctx_t *qctx) {
7904 CALL_HOOK(NS_QUERY_RESPOND_ANY_BEGIN, qctx);
7906 result = dns_db_allrdatasets(qctx->db, qctx->node, qctx->version, 0, 0,
7911 QUERY_ERROR(qctx, result);
7912 return ns_query_done(qctx);
7922 * If we do a query_addrrset() below, we must set qctx->fname to
7924 * cleanup qctx->fname even though we're using it!
7926 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
7927 qctx->tname = qctx->fname;
7931 dns_rdatasetiter_current(rdsiter, qctx->rdataset);
7936 if (qctx->qtype == dns_rdatatype_any &&
7937 qctx->rdataset->type == dns_rdatatype_ns)
7939 qctx->answer_has_ns = true;
7943 * Note: if we're in this function, then qctx->type
7944 * is guaranteed to be ANY, but qctx->qtype (i.e. the
7948 if (qctx->is_zone && qctx->qtype == dns_rdatatype_any &&
7949 !dns_db_issecure(qctx->db) &&
7950 dns_rdatatype_isdnssec(qctx->rdataset->type))
7956 dns_rdataset_disassociate(qctx->rdataset);
7958 } else if (qctx->view->minimal_any && !TCP(qctx->client) &&
7959 !WANTDNSSEC(qctx->client) &&
7960 qctx->qtype == dns_rdatatype_any &&
7961 (qctx->rdataset->type == dns_rdatatype_sig ||
7962 qctx->rdataset->type == dns_rdatatype_rrsig))
7966 dns_rdataset_disassociate(qctx->rdataset);
7967 } else if (qctx->view->minimal_any && !TCP(qctx->client) &&
7968 onetype != 0 && qctx->rdataset->type != onetype &&
7969 qctx->rdataset->covers != onetype)
7973 dns_rdataset_disassociate(qctx->rdataset);
7974 } else if ((qctx->qtype == dns_rdatatype_any ||
7975 qctx->rdataset->type == qctx->qtype) &&
7976 qctx->rdataset->type != 0)
7978 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client))
7980 qctx->noqname = qctx->rdataset;
7982 qctx->noqname = NULL;
7985 qctx->rpz_st = qctx->client->query.rpz_st;
7986 if (qctx->rpz_st != NULL) {
7987 qctx->rdataset->ttl =
7988 ISC_MIN(qctx->rdataset->ttl,
7989 qctx->rpz_st->m.ttl);
7992 if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
7994 name = (qctx->fname != NULL) ? qctx->fname
7995 : qctx->tname;
7996 query_prefetch(qctx->client, name,
7997 qctx->rdataset);
8004 if (qctx->rdataset->type == dns_rdatatype_sig ||
8005 qctx->rdataset->type == dns_rdatatype_rrsig)
8007 onetype = qctx->rdataset->covers;
8009 onetype = qctx->rdataset->type;
8012 query_addrrset(qctx,
8013 (qctx->fname != NULL) ? &qctx->fname
8014 : &qctx->tname,
8015 &qctx->rdataset, NULL, NULL,
8018 query_addnoqnameproof(qctx);
8021 INSIST(qctx->tname != NULL);
8027 if (qctx->rdataset != NULL) {
8028 ns_client_putrdataset(qctx->client,
8029 &qctx->rdataset);
8032 qctx->rdataset = ns_client_newrdataset(qctx->client);
8037 dns_rdataset_disassociate(qctx->rdataset);
8048 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
8049 return ns_query_done(qctx);
8055 * Do this before releasing qctx->fname, in case
8058 CALL_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx);
8061 if (qctx->fname != NULL) {
8062 dns_message_puttempname(qctx->client->message, &qctx->fname);
8069 query_addauth(qctx);
8070 } else if (qctx->qtype == dns_rdatatype_rrsig ||
8071 qctx->qtype == dns_rdatatype_sig)
8077 if (!qctx->is_zone) {
8078 qctx->authoritative = false;
8079 qctx->client->attributes &= ~NS_CLIENTATTR_RA;
8080 query_addauth(qctx);
8081 return ns_query_done(qctx);
8084 if (qctx->qtype == dns_rdatatype_rrsig &&
8085 dns_db_issecure(qctx->db))
8088 dns_name_format(qctx->client->query.qname, namebuf,
8090 ns_client_log(qctx->client, DNS_LOGCATEGORY_DNSSEC,
8095 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
8096 return query_sign_nodata(qctx);
8102 QUERY_ERROR(qctx, DNS_R_SERVFAIL);
8105 return ns_query_done(qctx);
8116 query_getexpire(query_ctx_t *qctx) {
8121 if (qctx->zone == NULL || !qctx->is_zone ||
8122 qctx->qtype != dns_rdatatype_soa ||
8123 qctx->client->query.restarts != 0 ||
8124 (qctx->client->attributes & NS_CLIENTATTR_WANTEXPIRE) == 0)
8129 dns_zone_getraw(qctx->zone, &raw);
8130 mayberaw = (raw != NULL) ? raw : qctx->zone;
8137 dns_zone_getexpiretime(qctx->zone, &expiretime);
8139 if (secs >= qctx->client->now && qctx->result == ISC_R_SUCCESS)
8141 qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
8142 qctx->client->expire = secs - qctx->client->now;
8149 result = dns_rdataset_first(qctx->rdataset);
8152 dns_rdataset_current(qctx->rdataset, &rdata);
8156 qctx->client->expire = soa.expire;
8157 qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
8169 query_addanswer(query_ctx_t *qctx) {
8175 CALL_HOOK(NS_QUERY_ADDANSWER_BEGIN, qctx);
8183 if (QUERY_STALEOK(&qctx->client->query) &&
8184 !QUERY_STALETIMEOUT(&qctx->client->query) && !qctx->refresh_rrset)
8187 query_clear_stale(qctx->client);
8192 qctx->client->query.attributes &= ~NS_QUERYATTR_STALEOK;
8195 if (qctx->dns64) {
8196 result = query_dns64(qctx);
8197 qctx->noqname = NULL;
8198 dns_rdataset_disassociate(qctx->rdataset);
8199 dns_message_puttemprdataset(qctx->client->message,
8200 &qctx->rdataset);
8203 if (qctx->dns64_exclude) {
8204 if (!qctx->is_zone) {
8205 return ns_query_done(qctx);
8210 (void)query_addsoa(qctx, 600,
8212 return ns_query_done(qctx);
8215 if (qctx->is_zone) {
8216 return query_nodata(qctx, DNS_R_NXDOMAIN);
8218 return query_ncache(qctx, DNS_R_NXDOMAIN);
8221 qctx->result = result;
8222 return ns_query_done(qctx);
8224 } else if (qctx->client->query.dns64_aaaaok != NULL) {
8225 query_filter64(qctx);
8226 ns_client_putrdataset(qctx->client, &qctx->rdataset);
8228 if (!qctx->is_zone && RECURSIONOK(qctx->client) &&
8229 !QUERY_STALETIMEOUT(&qctx->client->query))
8231 query_prefetch(qctx->client, qctx->fname,
8232 qctx->rdataset);
8234 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
8235 sigrdatasetp = &qctx->sigrdataset;
8237 query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
8238 sigrdatasetp, qctx->dbuf, DNS_SECTION_ANSWER);
8252 query_respond(query_ctx_t *qctx) {
8261 INSIST(qctx->client->query.dns64_aaaaok == NULL);
8263 if (qctx->qtype == dns_rdatatype_aaaa && !qctx->dns64_exclude &&
8264 !ISC_LIST_EMPTY(qctx->view->dns64) &&
8265 qctx->client->message->rdclass == dns_rdataclass_in &&
8266 !dns64_aaaaok(qctx->client, qctx->rdataset, qctx->sigrdataset))
8271 qctx->client->query.dns64_ttl = qctx->rdataset->ttl;
8272 SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset);
8273 SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset);
8274 ns_client_releasename(qctx->client, &qctx->fname);
8275 dns_db_detachnode(qctx->db, &qctx->node);
8276 qctx->type = qctx->qtype = dns_rdatatype_a;
8277 qctx->dns64_exclude = qctx->dns64 = true;
8279 return query_lookup(qctx);
8290 CALL_HOOK(NS_QUERY_RESPOND_BEGIN, qctx);
8292 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
8293 qctx->noqname = qctx->rdataset;
8295 qctx->noqname = NULL;
8301 if (qctx->is_zone && qctx->qtype == dns_rdatatype_ns) {
8306 if (dns_name_equal(qctx->client->query.qname,
8307 dns_db_origin(qctx->db)))
8309 qctx->answer_has_ns = true;
8316 if (dns_name_equal(qctx->client->query.qname, dns_rootname)) {
8317 qctx->client->query.attributes &=
8319 dns_db_attach(qctx->db, &qctx->client->query.gluedb);
8326 query_getexpire(qctx);
8328 result = query_addanswer(qctx);
8333 query_addnoqnameproof(qctx);
8336 * 'qctx->rdataset' will only be non-NULL here if the ANSWER section of
8338 * the same owner name and the same type as 'qctx->rdataset'. This
8342 * knowing that until now. In such a case, 'qctx->rdataset' will be
8345 INSIST(qctx->rdataset == NULL || qctx->qtype == dns_rdatatype_dname);
8347 query_addauth(qctx);
8349 return ns_query_done(qctx);
8356 query_dns64(query_ctx_t *qctx) {
8357 ns_client_t *client = qctx->client;
8375 * To the current response for 'qctx->client', add the answer RRset
8380 * If 'qctx->dbuf' is not NULL, then 'qctx->fname' is the name
8381 * whose data is stored 'qctx->dbuf'. In this case,
8387 qctx->qtype = qctx->type = dns_rdatatype_aaaa;
8389 name = qctx->fname;
8398 qctx->rdataset->covers, &mname, &mrdataset);
8406 if (qctx->dbuf != NULL) {
8407 ns_client_releasename(client, &qctx->fname);
8414 if (qctx->dbuf != NULL) {
8415 ns_client_keepname(client, name, qctx->dbuf);
8418 qctx->fname = NULL;
8422 if (qctx->dbuf != NULL) {
8423 ns_client_releasename(client, &qctx->fname);
8427 if (qctx->rdataset->trust != dns_trust_secure) {
8435 dns_rdataset_count(qctx->rdataset));
8443 dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl,
8446 dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl, 600);
8457 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
8458 dns_rdataset_isassociated(qctx->sigrdataset))
8463 for (result = dns_rdataset_first(qctx->rdataset);
8465 result = dns_rdataset_next(qctx->rdataset))
8470 dns_rdataset_current(qctx->rdataset, &rdata);
8504 dns64_rdataset->trust = qctx->rdataset->trust;
8507 query_setorder(qctx, mname, dns64_rdataset);
8541 query_filter64(query_ctx_t *qctx) {
8542 ns_client_t *client = qctx->client;
8558 dns_rdataset_count(qctx->rdataset));
8560 name = qctx->fname;
8568 qctx->rdataset->covers, &mname, &myrdataset);
8576 if (qctx->dbuf != NULL) {
8577 ns_client_releasename(client, &qctx->fname);
8582 qctx->fname = NULL;
8585 if (qctx->dbuf != NULL) {
8586 ns_client_releasename(client, &qctx->fname);
8588 qctx->dbuf = NULL;
8591 if (qctx->rdataset->trust != dns_trust_secure) {
8596 16 * dns_rdataset_count(qctx->rdataset));
8603 myrdatalist->ttl = qctx->rdataset->ttl;
8606 for (result = dns_rdataset_first(qctx->rdataset);
8608 result = dns_rdataset_next(qctx->rdataset))
8613 dns_rdataset_current(qctx->rdataset, &rdata);
8634 if (qctx->dbuf != NULL) {
8635 ns_client_keepname(client, name, qctx->dbuf);
8638 qctx->dbuf = NULL;
8640 myrdataset->trust = qctx->rdataset->trust;
8643 query_setorder(qctx, mname, myrdataset);
8669 if (qctx->dbuf != NULL) {
8682 query_notfound(query_ctx_t *qctx) {
8687 CALL_HOOK(NS_QUERY_NOTFOUND_BEGIN, qctx);
8689 INSIST(!qctx->is_zone);
8691 if (qctx->db != NULL) {
8692 dns_db_detach(&qctx->db);
8699 if (qctx->view->hints != NULL) {
8704 dns_clientinfo_init(&ci, qctx->client, NULL);
8706 dns_db_attach(qctx->view->hints, &qctx->db);
8707 result = dns_db_findext(qctx->db, dns_rootname, NULL,
8708 dns_rdatatype_ns, 0, qctx->client->now,
8709 &qctx->node, qctx->fname, &cm, &ci,
8710 qctx->rdataset, qctx->sigrdataset);
8719 qctx_clean(qctx);
8726 if (RECURSIONOK(qctx->client)) {
8727 INSIST(!REDIRECT(qctx->client));
8728 result = ns_query_recurse(qctx->client, qctx->qtype,
8729 qctx->client->query.qname,
8730 NULL, NULL, qctx->resuming);
8732 CALL_HOOK(NS_QUERY_NOTFOUND_RECURSE, qctx);
8733 qctx->client->query.attributes |=
8736 if (qctx->dns64) {
8737 qctx->client->query.attributes |=
8740 if (qctx->dns64_exclude) {
8741 qctx->client->query.attributes |=
8744 } else if (query_usestale(qctx, result)) {
8747 * already set up 'qctx' for looking up a
8750 return query_lookup(qctx);
8752 QUERY_ERROR(qctx, result);
8754 return ns_query_done(qctx);
8759 QUERY_ERROR(qctx, result);
8760 return ns_query_done(qctx);
8764 return query_delegation(qctx);
8775 query_prepare_delegation_response(query_ctx_t *qctx) {
8780 CALL_HOOK(NS_QUERY_PREP_DELEGATION_BEGIN, qctx);
8783 * qctx->fname could be released in query_addrrset(), so save a copy of
8786 dns_fixedname_init(&qctx->dsname);
8787 dns_name_copy(qctx->fname, dns_fixedname_name(&qctx->dsname));
8792 qctx->client->query.isreferral = true;
8794 if (!dns_db_iscache(qctx->db) && qctx->client->query.gluedb == NULL) {
8795 dns_db_attach(qctx->db, &qctx->client->query.gluedb);
8803 qctx->client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
8804 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
8805 sigrdatasetp = &qctx->sigrdataset;
8807 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp,
8808 qctx->dbuf, DNS_SECTION_AUTHORITY);
8810 dns_db_detach(&qctx->client->query.gluedb);
8816 query_addds(qctx);
8818 return ns_query_done(qctx);
8831 query_zone_delegation(query_ctx_t *qctx) {
8834 CALL_HOOK(NS_QUERY_ZONE_DELEGATION_BEGIN, qctx);
8840 if (!RECURSIONOK(qctx->client) &&
8841 (qctx->options.noexact && qctx->qtype == dns_rdatatype_ds))
8847 result = query_getzonedb(qctx->client,
8848 qctx->client->query.qname, qctx->qtype,
8858 qctx->options.noexact = false;
8859 ns_client_putrdataset(qctx->client, &qctx->rdataset);
8860 if (qctx->sigrdataset != NULL) {
8861 ns_client_putrdataset(qctx->client,
8862 &qctx->sigrdataset);
8864 if (qctx->fname != NULL) {
8865 ns_client_releasename(qctx->client,
8866 &qctx->fname);
8868 if (qctx->node != NULL) {
8869 dns_db_detachnode(qctx->db, &qctx->node);
8871 if (qctx->db != NULL) {
8872 dns_db_detach(&qctx->db);
8874 if (qctx->zone != NULL) {
8875 dns_zone_detach(&qctx->zone);
8877 qctx->version = NULL;
8878 RESTORE(qctx->version, tversion);
8879 RESTORE(qctx->db, tdb);
8880 RESTORE(qctx->zone, tzone);
8881 qctx->authoritative = true;
8883 return query_lookup(qctx);
8887 if (USECACHE(qctx->client) &&
8888 (RECURSIONOK(qctx->client) ||
8889 (qctx->zone != NULL &&
8890 dns_zone_gettype(qctx->zone) == dns_zone_mirror)))
8901 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8902 SAVE(qctx->zdb, qctx->db);
8903 SAVE(qctx->znode, qctx->node);
8904 SAVE(qctx->zfname, qctx->fname);
8905 SAVE(qctx->zversion, qctx->version);
8906 SAVE(qctx->zrdataset, qctx->rdataset);
8907 SAVE(qctx->zsigrdataset, qctx->sigrdataset);
8908 dns_db_attach(qctx->view->cachedb, &qctx->db);
8909 qctx->is_zone = false;
8911 return query_lookup(qctx);
8914 return query_prepare_delegation_response(qctx);
8929 query_delegation(query_ctx_t *qctx) {
8934 CALL_HOOK(NS_QUERY_DELEGATION_BEGIN, qctx);
8936 qctx->authoritative = false;
8938 if (qctx->is_zone) {
8939 return query_zone_delegation(qctx);
8942 if (qctx->zfname != NULL &&
8943 (!dns_name_issubdomain(qctx->fname, qctx->zfname) ||
8944 (qctx->is_staticstub_zone &&
8945 dns_name_equal(qctx->fname, qctx->zfname))))
8962 ns_client_releasename(qctx->client, &qctx->fname);
8966 * qctx->zfname, so we must set dbuf to NULL to
8970 qctx->dbuf = NULL;
8971 ns_client_putrdataset(qctx->client, &qctx->rdataset);
8972 if (qctx->sigrdataset != NULL) {
8973 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
8975 qctx->version = NULL;
8977 dns_db_detachnode(qctx->db, &qctx->node);
8978 dns_db_detach(&qctx->db);
8979 RESTORE(qctx->db, qctx->zdb);
8980 RESTORE(qctx->node, qctx->znode);
8981 RESTORE(qctx->fname, qctx->zfname);
8982 RESTORE(qctx->version, qctx->zversion);
8983 RESTORE(qctx->rdataset, qctx->zrdataset);
8984 RESTORE(qctx->sigrdataset, qctx->zsigrdataset);
8987 result = query_delegation_recurse(qctx);
8992 return query_prepare_delegation_response(qctx);
9003 query_delegation_recurse(query_ctx_t *qctx) {
9005 dns_name_t *qname = qctx->client->query.qname;
9009 if (!RECURSIONOK(qctx->client)) {
9013 CALL_HOOK(NS_QUERY_DELEGATION_RECURSE_BEGIN, qctx);
9023 INSIST(!REDIRECT(qctx->client));
9025 if (dns_rdatatype_atparent(qctx->type)) {
9029 result = ns_query_recurse(qctx->client, qctx->qtype, qname,
9030 NULL, NULL, qctx->resuming);
9031 } else if (qctx->dns64) {
9035 result = ns_query_recurse(qctx->client, dns_rdatatype_a, qname,
9036 NULL, NULL, qctx->resuming);
9041 result = ns_query_recurse(qctx->client, qctx->qtype, qname,
9042 qctx->fname, qctx->rdataset,
9043 qctx->resuming);
9047 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
9048 if (qctx->dns64) {
9049 qctx->client->query.attributes |= NS_QUERYATTR_DNS64;
9051 if (qctx->dns64_exclude) {
9052 qctx->client->query.attributes |=
9055 } else if (query_usestale(qctx, result)) {
9058 * 'qctx' for looking up a stale response.
9060 return query_lookup(qctx);
9062 QUERY_ERROR(qctx, result);
9065 return ns_query_done(qctx);
9075 query_addds(query_ctx_t *qctx) {
9076 ns_client_t *client = qctx->client;
9104 result = dns_db_findrdataset(qctx->db, qctx->node, qctx->version,
9112 qctx->db, qctx->node, qctx->version, dns_rdatatype_nsec,
9157 query_addrrset(qctx, &rname, &rdataset, &sigrdataset, NULL,
9162 if (!dns_db_iszone(qctx->db)) {
9177 name = dns_fixedname_name(&qctx->dsname);
9178 query_findclosestnsec3(name, qctx->db, qctx->version, client, rdataset,
9184 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
9201 query_findclosestnsec3(dns_fixedname_name(&fixed), qctx->db,
9202 qctx->version, client, rdataset,
9207 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
9227 query_nodata(query_ctx_t *qctx, isc_result_t res) {
9232 CALL_HOOK(NS_QUERY_NODATA_BEGIN, qctx);
9235 if (qctx->dns64)
9237 if (qctx->dns64 && !qctx->dns64_exclude)
9244 if (qctx->rdataset != NULL) {
9245 ns_client_putrdataset(qctx->client, &qctx->rdataset);
9247 if (qctx->sigrdataset != NULL) {
9248 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
9250 RESTORE(qctx->rdataset, qctx->client->query.dns64_aaaa);
9251 RESTORE(qctx->sigrdataset, qctx->client->query.dns64_sigaaaa);
9252 if (qctx->fname == NULL) {
9253 qctx->dbuf = ns_client_getnamebuf(qctx->client);
9254 qctx->fname = ns_client_newname(qctx->client,
9255 qctx->dbuf, &b);
9257 dns_name_copy(qctx->client->query.qname, qctx->fname);
9258 qctx->dns64 = false;
9263 if (qctx->dns64_exclude) {
9264 return query_prepresponse(qctx);
9268 !ISC_LIST_EMPTY(qctx->view->dns64) && !qctx->nxrewrite &&
9269 qctx->client->message->rdclass == dns_rdataclass_in &&
9270 qctx->qtype == dns_rdatatype_aaaa)
9283 if (qctx->rdataset->ttl != 0) {
9284 qctx->client->query.dns64_ttl =
9285 qctx->rdataset->ttl;
9288 if (dns_rdataset_first(qctx->rdataset) == ISC_R_SUCCESS)
9290 qctx->client->query.dns64_ttl = 0;
9294 qctx->client->query.dns64_ttl =
9295 dns64_ttl(qctx->db, qctx->version);
9301 SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset);
9302 SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset);
9303 ns_client_releasename(qctx->client, &qctx->fname);
9304 dns_db_detachnode(qctx->db, &qctx->node);
9305 qctx->type = qctx->qtype = dns_rdatatype_a;
9306 qctx->dns64 = true;
9307 return query_lookup(qctx);
9310 if (qctx->is_zone) {
9311 return query_sign_nodata(qctx);
9317 if (dns_rdataset_isassociated(qctx->rdataset)) {
9318 ns_client_keepname(qctx->client, qctx->fname,
9319 qctx->dbuf);
9320 dns_message_addname(qctx->client->message, qctx->fname,
9322 ISC_LIST_APPEND(qctx->fname->list, qctx->rdataset,
9324 qctx->fname = NULL;
9325 qctx->rdataset = NULL;
9329 return ns_query_done(qctx);
9339 query_sign_nodata(query_ctx_t *qctx) {
9347 if (qctx->redirected) {
9348 return ns_query_done(qctx);
9350 if (!dns_rdataset_isassociated(qctx->rdataset) &&
9351 WANTDNSSEC(qctx->client))
9353 if (!qctx->fname->attributes.wildcard) {
9360 qname = qctx->client->query.qname;
9362 query_findclosestnsec3(qname, qctx->db, qctx->version,
9363 qctx->client, qctx->rdataset,
9364 qctx->sigrdataset, qctx->fname,
9371 if (dns_rdataset_isassociated(qctx->rdataset) &&
9373 (((qctx->client->manager->sctx->options &
9375 qctx->qtype == dns_rdatatype_ds))
9383 query_addrrset(qctx, &qctx->fname,
9384 &qctx->rdataset,
9385 &qctx->sigrdataset, qctx->dbuf,
9393 fixfname(qctx->client, &qctx->fname,
9394 &qctx->dbuf, &b);
9395 fixrdataset(qctx->client, &qctx->rdataset);
9396 fixrdataset(qctx->client, &qctx->sigrdataset);
9397 if (qctx->fname == NULL ||
9398 qctx->rdataset == NULL ||
9399 qctx->sigrdataset == NULL)
9407 QUERY_ERROR(qctx, ISC_R_NOMEMORY);
9408 return ns_query_done(qctx);
9415 found, qctx->db, qctx->version,
9416 qctx->client, qctx->rdataset,
9417 qctx->sigrdataset, qctx->fname, false,
9421 ns_client_releasename(qctx->client, &qctx->fname);
9422 query_addwildcardproof(qctx, false, true);
9425 if (dns_rdataset_isassociated(qctx->rdataset)) {
9431 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9432 } else if (qctx->fname != NULL) {
9438 ns_client_releasename(qctx->client, &qctx->fname);
9445 if (!qctx->nxrewrite) {
9446 result = query_addsoa(qctx, UINT32_MAX, DNS_SECTION_AUTHORITY);
9448 QUERY_ERROR(qctx, result);
9449 return ns_query_done(qctx);
9456 if (WANTDNSSEC(qctx->client) &&
9457 dns_rdataset_isassociated(qctx->rdataset))
9459 query_addnxrrsetnsec(qctx);
9462 return ns_query_done(qctx);
9466 query_addnxrrsetnsec(query_ctx_t *qctx) {
9467 ns_client_t *client = qctx->client;
9475 INSIST(qctx->fname != NULL);
9477 if (!qctx->fname->attributes.wildcard) {
9478 query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
9479 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
9483 if (qctx->sigrdataset == NULL ||
9484 !dns_rdataset_isassociated(qctx->sigrdataset))
9489 if (dns_rdataset_first(qctx->sigrdataset) != ISC_R_SUCCESS) {
9494 dns_rdataset_current(qctx->sigrdataset, &sigrdata);
9498 labels = dns_name_countlabels(qctx->fname);
9503 query_addwildcardproof(qctx, true, false);
9511 dns_name_split(qctx->fname, sig.labels + 1, NULL, fname);
9515 query_addrrset(qctx, &fname, &qctx->rdataset, &qctx->sigrdataset, dbuf,
9523 query_nxdomain(query_ctx_t *qctx, isc_result_t result) {
9530 CALL_HOOK(NS_QUERY_NXDOMAIN_BEGIN, qctx);
9532 INSIST(qctx->is_zone || REDIRECT(qctx->client));
9535 result = query_redirect(qctx, result);
9541 if (dns_rdataset_isassociated(qctx->rdataset)) {
9547 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9548 } else if (qctx->fname != NULL) {
9554 ns_client_releasename(qctx->client, &qctx->fname);
9566 section = qctx->nxrewrite ? DNS_SECTION_ADDITIONAL
9569 if (!qctx->nxrewrite && qctx->qtype == dns_rdatatype_soa &&
9570 qctx->zone != NULL && dns_zone_getzeronosoattl(qctx->zone))
9574 if (!qctx->nxrewrite ||
9575 (qctx->rpz_st != NULL && qctx->rpz_st->m.rpz->addsoa))
9577 result = query_addsoa(qctx, ttl, section);
9579 QUERY_ERROR(qctx, result);
9580 return ns_query_done(qctx);
9584 if (WANTDNSSEC(qctx->client)) {
9588 if (dns_rdataset_isassociated(qctx->rdataset)) {
9589 query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
9590 &qctx->sigrdataset, NULL,
9593 query_addwildcardproof(qctx, false, false);
9600 qctx->client->message->rcode = dns_rcode_noerror;
9602 qctx->client->message->rcode = dns_rcode_nxdomain;
9605 return ns_query_done(qctx);
9623 query_redirect(query_ctx_t *qctx, isc_result_t saved_result) {
9628 result = redirect(qctx->client, qctx->fname, qctx->rdataset,
9629 &qctx->node, &qctx->db, &qctx->version, qctx->type);
9632 inc_stats(qctx->client, ns_statscounter_nxdomainredirect);
9633 return query_prepresponse(qctx);
9635 qctx->redirected = true;
9636 qctx->is_zone = true;
9637 return query_nodata(qctx, DNS_R_NXRRSET);
9639 qctx->redirected = true;
9640 qctx->is_zone = false;
9641 return query_ncache(qctx, DNS_R_NCACHENXRRSET);
9646 result = redirect2(qctx->client, qctx->fname, qctx->rdataset,
9647 &qctx->node, &qctx->db, &qctx->version, qctx->type,
9648 &qctx->is_zone);
9651 inc_stats(qctx->client, ns_statscounter_nxdomainredirect);
9652 return query_prepresponse(qctx);
9654 inc_stats(qctx->client,
9656 SAVE(qctx->client->query.redirect.db, qctx->db);
9657 SAVE(qctx->client->query.redirect.node, qctx->node);
9658 SAVE(qctx->client->query.redirect.zone, qctx->zone);
9659 qctx->client->query.redirect.qtype = qctx->qtype;
9660 INSIST(qctx->rdataset != NULL);
9661 SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
9662 SAVE(qctx->client->query.redirect.sigrdataset,
9663 qctx->sigrdataset);
9664 qctx->client->query.redirect.result = saved_result;
9665 dns_name_copy(qctx->fname, qctx->client->query.redirect.fname);
9666 qctx->client->query.redirect.authoritative =
9667 qctx->authoritative;
9668 qctx->client->query.redirect.is_zone = qctx->is_zone;
9669 return ns_query_done(qctx);
9671 qctx->redirected = true;
9672 qctx->is_zone = true;
9673 return query_nodata(qctx, DNS_R_NXRRSET);
9675 qctx->redirected = true;
9676 qctx->is_zone = false;
9677 return query_ncache(qctx, DNS_R_NCACHENXRRSET);
9690 query_ctx_t *qctx = val;
9694 ns_client_logv(qctx->client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
9737 query_synthnodata(query_ctx_t *qctx, const dns_name_t *signer,
9747 ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, qctx->rdataset,
9748 qctx->sigrdataset, NULL, NULL);
9755 if (WANTDNSSEC(qctx->client)) {
9756 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9758 ns_client_releasename(qctx->client, &qctx->fname);
9761 dbuf = ns_client_getnamebuf(qctx->client);
9762 name = ns_client_newname(qctx->client, dbuf, &b);
9768 if (!WANTDNSSEC(qctx->client)) {
9771 query_addrrset(qctx, &name, soardatasetp, sigsoardatasetp, dbuf,
9774 if (WANTDNSSEC(qctx->client)) {
9778 query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
9779 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
9782 inc_stats(qctx->client, ns_statscounter_nodatasynth);
9785 ns_client_releasename(qctx->client, &name);
9792 * qctx contains the NODATA proof.
9795 query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
9808 if (WANTDNSSEC(qctx->client)) {
9809 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9811 ns_client_releasename(qctx->client, &qctx->fname);
9814 dbuf = ns_client_getnamebuf(qctx->client);
9815 name = ns_client_newname(qctx->client, dbuf, &b);
9816 dns_name_copy(qctx->client->query.qname, name);
9818 cloneset = ns_client_newrdataset(qctx->client);
9824 if (WANTDNSSEC(qctx->client)) {
9825 clonesigset = ns_client_newrdataset(qctx->client);
9832 query_addrrset(qctx, &name, &cloneset, sigrdatasetp, dbuf,
9835 if (WANTDNSSEC(qctx->client)) {
9839 query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
9840 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
9843 inc_stats(qctx->client, ns_statscounter_wildcardsynth);
9846 ns_client_releasename(qctx->client, &name);
9849 ns_client_putrdataset(qctx->client, &cloneset);
9852 ns_client_putrdataset(qctx->client, &clonesigset);
9863 query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
9870 result = query_synthwildcard(qctx, rdataset, sigrdataset);
9875 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
9881 dns_message_gettempname(qctx->client->message, &tname);
9885 dns_message_puttempname(qctx->client->message, &tname);
9894 if (dns_name_equal(qctx->client->query.qname, &cname.cname)) {
9895 dns_message_puttempname(qctx->client->message, &tname);
9903 ns_client_qnamereplace(qctx->client, tname);
9904 qctx->want_restart = true;
9905 if (!WANTRECURSION(qctx->client)) {
9906 qctx->options.nolog = true;
9913 * Synthesize a NXDOMAIN or NODATA response from qctx (which contains the
9920 query_synthnxdomainnodata(query_ctx_t *qctx, bool nodata, dns_name_t *nowild,
9935 ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, qctx->rdataset,
9936 qctx->sigrdataset, nowildrdataset,
9944 if (WANTDNSSEC(qctx->client)) {
9945 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9947 ns_client_releasename(qctx->client, &qctx->fname);
9950 dbuf = ns_client_getnamebuf(qctx->client);
9951 name = ns_client_newname(qctx->client, dbuf, &b);
9957 if (!WANTDNSSEC(qctx->client)) {
9960 query_addrrset(qctx, &name, soardatasetp, sigsoardatasetp, dbuf,
9963 if (WANTDNSSEC(qctx->client)) {
9967 query_addrrset(qctx, &qctx->fname, &qctx->rdataset,
9968 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY);
9970 dbuf = ns_client_getnamebuf(qctx->client);
9971 name = ns_client_newname(qctx->client, dbuf, &b);
9974 cloneset = ns_client_newrdataset(qctx->client);
9975 clonesigset = ns_client_newrdataset(qctx->client);
9983 query_addrrset(qctx, &name, &cloneset, &clonesigset, dbuf,
9988 inc_stats(qctx->client, ns_statscounter_nodatasynth);
9990 qctx->client->message->rcode = dns_rcode_nxdomain;
9991 inc_stats(qctx->client, ns_statscounter_nxdomainsynth);
9995 ns_client_releasename(qctx->client, &name);
9998 ns_client_putrdataset(qctx->client, &cloneset);
10001 ns_client_putrdataset(qctx->client, &clonesigset);
10054 query_coveringnsec(query_ctx_t *qctx) {
10076 unsigned int dboptions = qctx->client->query.dboptions;
10091 dns_name_clone(qctx->client->query.qname, &qname);
10093 if (dns_rdatatype_atparent(qctx->qtype) && labels > 1) {
10096 dns_view_sfd_find(qctx->view, &qname, namespace);
10097 if (!dns_name_issubdomain(qctx->fname, namespace)) {
10104 if (!dns_rdataset_isassociated(qctx->sigrdataset)) {
10114 dns_clientinfo_init(&ci, qctx->client, NULL);
10119 result = checksignames(signer, qctx->sigrdataset);
10129 if (!dns_nsec_requiredtypespresent(qctx->rdataset)) {
10136 result = dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname,
10137 qctx->fname, qctx->rdataset, &exists,
10138 &data, wild, log_noexistnodata, qctx);
10145 if (qctx->type == dns_rdatatype_any) { /* XXX not yet */
10148 if (!ISC_LIST_EMPTY(qctx->view->dns64) &&
10149 (qctx->type == dns_rdatatype_a ||
10150 qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
10154 if (!qctx->resuming && !STALE(qctx->rdataset) &&
10155 qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client))
10160 soardataset = ns_client_newrdataset(qctx->client);
10161 sigsoardataset = ns_client_newrdataset(qctx->client);
10166 dns_db_attach(qctx->db, &db);
10167 result = dns_db_findext(db, signer, qctx->version,
10169 qctx->client->now, &node, fname, &cm,
10175 (void)query_synthnodata(qctx, signer, &soardataset,
10184 dns_db_attach(qctx->db, &db);
10185 result = dns_db_findext(db, wild, qctx->version, qctx->type,
10187 qctx->client->now, &node, nowild, &cm, &ci,
10205 if (qctx->type == dns_rdatatype_any) { /* XXX not yet */
10208 if (!ISC_LIST_EMPTY(qctx->view->dns64) &&
10209 (qctx->type == dns_rdatatype_a ||
10210 qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
10216 if (!qctx->resuming && !STALE(&rdataset) && rdataset.ttl == 0 &&
10217 RECURSIONOK(qctx->client))
10234 result = dns_nsec_noexistnodata(qctx->qtype, wild, nowild,
10236 log_noexistnodata, qctx);
10242 (void)query_synthwildcard(qctx, &rdataset, &sigrdataset);
10246 (void)query_synthcnamewildcard(qctx, &rdataset, &sigrdataset);
10259 result = query_redirect(qctx, DNS_R_COVERINGNSEC);
10285 soardataset = ns_client_newrdataset(qctx->client);
10286 sigsoardataset = ns_client_newrdataset(qctx->client);
10291 result = dns_db_findext(db, signer, qctx->version, dns_rdatatype_soa,
10292 dboptions, qctx->client->now, &node, fname, &cm,
10298 (void)query_synthnxdomainnodata(qctx, exists, nowild, &rdataset,
10311 ns_client_putrdataset(qctx->client, &soardataset);
10314 ns_client_putrdataset(qctx->client, &sigsoardataset);
10331 qctx->findcoveringnsec = false;
10332 if (qctx->fname != NULL) {
10333 ns_client_releasename(qctx->client, &qctx->fname);
10335 if (qctx->node != NULL) {
10336 dns_db_detachnode(qctx->db, &qctx->node);
10338 ns_client_putrdataset(qctx->client, &qctx->rdataset);
10339 if (qctx->sigrdataset != NULL) {
10340 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
10342 return query_lookup(qctx);
10345 return ns_query_done(qctx);
10354 query_ncache(query_ctx_t *qctx, isc_result_t result) {
10355 INSIST(!qctx->is_zone);
10361 CALL_HOOK(NS_QUERY_NCACHE_BEGIN, qctx);
10363 qctx->authoritative = false;
10372 qctx->client->message->rcode = dns_rcode_nxdomain;
10375 if (qctx->qtype == dns_rdatatype_ptr &&
10376 qctx->client->message->rdclass == dns_rdataclass_in &&
10377 dns_name_countlabels(qctx->fname) == 7)
10379 warn_rfc1918(qctx->client, qctx->fname, qctx->rdataset);
10383 return query_nodata(qctx, result);
10393 query_zerottl_refetch(query_ctx_t *qctx) {
10398 if (qctx->is_zone || qctx->resuming || STALE(qctx->rdataset) ||
10399 qctx->rdataset->ttl != 0 || !RECURSIONOK(qctx->client))
10404 qctx_clean(qctx);
10406 INSIST(!REDIRECT(qctx->client));
10408 result = ns_query_recurse(qctx->client, qctx->qtype,
10409 qctx->client->query.qname, NULL, NULL,
10410 qctx->resuming);
10412 CALL_HOOK(NS_QUERY_ZEROTTL_RECURSE, qctx);
10413 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
10415 if (qctx->dns64) {
10416 qctx->client->query.attributes |= NS_QUERYATTR_DNS64;
10418 if (qctx->dns64_exclude) {
10419 qctx->client->query.attributes |=
10427 QUERY_ERROR(qctx, result);
10430 return ns_query_done(qctx);
10440 query_cname(query_ctx_t *qctx) {
10450 CALL_HOOK(NS_QUERY_CNAME_BEGIN, qctx);
10452 result = query_zerottl_refetch(qctx);
10462 trdataset = qctx->rdataset;
10467 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
10468 sigrdatasetp = &qctx->sigrdataset;
10471 if (WANTDNSSEC(qctx->client) && qctx->fname->attributes.wildcard) {
10472 dns_fixedname_init(&qctx->wildcardname);
10473 dns_name_copy(qctx->fname,
10474 dns_fixedname_name(&qctx->wildcardname));
10475 qctx->need_wildcardproof = true;
10478 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
10479 qctx->noqname = qctx->rdataset;
10481 qctx->noqname = NULL;
10484 if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
10485 query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
10488 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp,
10489 qctx->dbuf, DNS_SECTION_ANSWER);
10491 query_addnoqnameproof(qctx);
10497 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
10503 dns_message_gettempname(qctx->client->message, &tname);
10507 dns_message_puttempname(qctx->client->message, &tname);
10508 (void)ns_query_done(qctx);
10520 ns_client_qnamereplace(qctx->client, tname);
10521 qctx->want_restart = true;
10522 if (!WANTRECURSION(qctx->client)) {
10523 qctx->options.nolog = true;
10526 query_addauth(qctx);
10528 return ns_query_done(qctx);
10538 query_dname(query_ctx_t *qctx) {
10553 CALL_HOOK(NS_QUERY_DNAME_BEGIN, qctx);
10560 namereln = dns_name_fullcompare(qctx->client->query.qname, qctx->fname,
10569 trdataset = qctx->rdataset;
10574 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
10575 sigrdatasetp = &qctx->sigrdataset;
10578 if (WANTDNSSEC(qctx->client) && qctx->fname->attributes.wildcard) {
10579 dns_fixedname_init(&qctx->wildcardname);
10580 dns_name_copy(qctx->fname,
10581 dns_fixedname_name(&qctx->wildcardname));
10582 qctx->need_wildcardproof = true;
10585 if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
10586 query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
10588 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp,
10589 qctx->dbuf, DNS_SECTION_ANSWER);
10595 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
10601 dns_message_gettempname(qctx->client->message, &tname);
10605 dns_message_puttempname(qctx->client->message, &tname);
10606 (void)ns_query_done(qctx);
10623 dns_name_split(qctx->client->query.qname, nlabels, prefix, NULL);
10624 INSIST(qctx->fname == NULL);
10625 qctx->dbuf = ns_client_getnamebuf(qctx->client);
10626 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
10627 result = dns_name_concatenate(prefix, tname, qctx->fname, NULL);
10628 dns_message_puttempname(qctx->client->message, &tname);
10636 qctx->client->message->rcode = dns_rcode_yxdomain;
10639 (void)ns_query_done(qctx);
10643 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
10659 query_addcname(qctx, trdataset->trust, trdataset->ttl);
10665 if (qctx->qtype != dns_rdatatype_cname &&
10666 qctx->qtype != dns_rdatatype_any)
10671 ns_client_qnamereplace(qctx->client, qctx->fname);
10672 qctx->fname = NULL;
10673 qctx->want_restart = true;
10674 if (!WANTRECURSION(qctx->client)) {
10675 qctx->options.nolog = true;
10679 query_addauth(qctx);
10681 return ns_query_done(qctx);
10691 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) {
10692 ns_client_t *client = qctx->client;
10713 dns_name_toregion(qctx->fname, &r);
10724 query_addrrset(qctx, &aname, &rdataset, NULL, NULL, DNS_SECTION_ANSWER);
10742 query_prepresponse(query_ctx_t *qctx) {
10747 CALL_HOOK(NS_QUERY_PREP_RESPONSE_BEGIN, qctx);
10749 if (WANTDNSSEC(qctx->client) && qctx->fname->attributes.wildcard) {
10750 dns_fixedname_init(&qctx->wildcardname);
10751 dns_name_copy(qctx->fname,
10752 dns_fixedname_name(&qctx->wildcardname));
10753 qctx->need_wildcardproof = true;
10756 if (qctx->type == dns_rdatatype_any) {
10757 return query_respond_any(qctx);
10760 result = query_zerottl_refetch(qctx);
10765 return query_respond(qctx);
10777 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl,
10779 ns_client_t *client = qctx->client;
10797 (!WANTDNSSEC(client) || !dns_rdataset_isassociated(qctx->rdataset)))
10811 dns_name_clone(dns_db_origin(qctx->db), name);
10814 if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
10821 result = dns_db_getoriginnode(qctx->db, &node);
10823 result = dns_db_findrdataset(qctx->db, node, qctx->version,
10832 result = dns_db_findext(qctx->db, name, qctx->version,
10884 query_addrrset(qctx, &name, &rdataset, sigrdatasetp, NULL,
10896 dns_db_detachnode(qctx->db, &node);
10906 query_addns(query_ctx_t *qctx) {
10907 ns_client_t *client = qctx->client;
10932 dns_name_clone(dns_db_origin(qctx->db), name);
10935 if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
10942 result = dns_db_getoriginnode(qctx->db, &node);
10944 result = dns_db_findrdataset(qctx->db, node, qctx->version,
10949 result = dns_db_findext(qctx->db, name, NULL, dns_rdatatype_ns,
10967 query_addrrset(qctx, &name, &rdataset, sigrdatasetp, NULL,
10980 dns_db_detachnode(qctx->db, &node);
10991 query_addbestns(query_ctx_t *qctx) {
10992 ns_client_t *client = qctx->client;
11178 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
11213 query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata) {
11214 ns_client_t *client = qctx->client;
11242 * qctx->wildcardname. Otherwise we just use the client
11245 if (qctx->need_wildcardproof) {
11246 name = dns_fixedname_name(&qctx->wildcardname);
11305 result = dns_db_findext(qctx->db, name, qctx->version,
11309 dns_db_detachnode(qctx->db, &node);
11333 result = dns_db_findext(qctx->db, cname, qctx->version,
11347 query_findclosestnsec3(cname, qctx->db, qctx->version, client,
11354 query_addrrset(qctx, &fname, &rdataset, &sigrdataset,
11388 query_findclosestnsec3(wname, qctx->db, qctx->version, client,
11394 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
11430 query_findclosestnsec3(wname, qctx->db, qctx->version, client,
11436 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
11472 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
11508 query_addauth(query_ctx_t *qctx) {
11514 if (!qctx->want_restart && !NOAUTHORITY(qctx->client)) {
11515 if (qctx->is_zone) {
11516 if (!qctx->answer_has_ns) {
11517 (void)query_addns(qctx);
11519 } else if (!qctx->answer_has_ns &&
11520 qctx->qtype != dns_rdatatype_ns)
11522 if (qctx->fname != NULL) {
11523 ns_client_releasename(qctx->client,
11524 &qctx->fname);
11526 query_addbestns(qctx);
11534 if (qctx->need_wildcardproof && dns_db_issecure(qctx->db)) {
11535 query_addwildcardproof(qctx, true, false);
11573 query_setup_sortlist(query_ctx_t *qctx) {
11575 ns_client_t *client = qctx->client;
11610 query_glueanswer(query_ctx_t *qctx) {
11611 const dns_namelist_t *secs = qctx->client->message->sections;
11618 qctx->client->message->rcode != dns_rcode_noerror ||
11619 (qctx->qtype != dns_rdatatype_a &&
11620 qctx->qtype != dns_rdatatype_aaaa))
11625 msg = qctx->client->message;
11629 if (dns_name_equal(name, qctx->client->query.qname)) {
11634 if (rdataset->type == qctx->qtype) {
11651 ns_query_done(query_ctx_t *qctx) {
11653 const dns_namelist_t *secs = qctx->client->message->sections;
11658 CALL_HOOK(NS_QUERY_DONE_BEGIN, qctx);
11663 qctx->rpz_st = qctx->client->query.rpz_st;
11664 if (qctx->rpz_st != NULL &&
11665 (qctx->rpz_st->state & DNS_RPZ_RECURSING) == 0)
11667 rpz_match_clear(qctx->rpz_st);
11668 qctx->rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
11671 qctx_clean(qctx);
11672 qctx_freedata(qctx);
11674 if (qctx->client->query.gluedb != NULL) {
11675 dns_db_detach(&qctx->client->query.gluedb);
11681 if (qctx->client->query.restarts == 0 && !qctx->authoritative) {
11682 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
11688 if (qctx->want_restart) {
11689 if (qctx->client->query.restarts <
11690 qctx->client->view->max_restarts)
11693 qctx->client->query.restarts++;
11694 saved_qctx = isc_mem_get(qctx->client->manager->mctx,
11696 qctx_save(qctx, saved_qctx);
11697 isc_nmhandle_attach(qctx->client->handle,
11698 &qctx->client->restarthandle);
11699 isc_async_run(qctx->client->manager->loop,
11706 qctx->client->query.attributes |=
11708 qctx->client->message->rcode = dns_rcode_servfail;
11709 qctx->result = DNS_R_SERVFAIL;
11717 ns_client_extendederror(qctx->client, 0,
11719 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
11725 if (qctx->result != ISC_R_SUCCESS &&
11726 (!PARTIALANSWER(qctx->client) ||
11727 (WANTRECURSION(qctx->client) && !partial_result_with_servfail) ||
11728 qctx->result == DNS_R_DROP))
11730 if (qctx->result == DNS_R_DUPLICATE ||
11731 qctx->result == DNS_R_DROP)
11739 query_next(qctx->client, qctx->result);
11746 INSIST(qctx->line >= 0);
11747 query_error(qctx->client, qctx->result, qctx->line);
11750 qctx->detach_client = true;
11751 return qctx->result;
11758 if (RECURSING(qctx->client) &&
11759 (!QUERY_STALETIMEOUT(&qctx->client->query) ||
11760 qctx->options.stalefirst))
11762 return qctx->result;
11772 query_setup_sortlist(qctx);
11773 query_glueanswer(qctx);
11775 if (qctx->client->message->rcode == dns_rcode_nxdomain &&
11776 qctx->view->auth_nxdomain)
11778 qctx->client->message->flags |= DNS_MESSAGEFLAG_AA;
11786 if (qctx->resuming &&
11788 qctx->client->message->rcode != dns_rcode_noerror))
11790 qctx->result = ISC_R_FAILURE;
11793 CALL_HOOK(NS_QUERY_DONE_SEND, qctx);
11795 query_send(qctx->client);
11797 if (qctx->refresh_rrset) {
11807 message_clearrdataset(qctx->client->message, 0);
11808 query_stale_refresh(qctx->client);
11811 qctx->detach_client = true;
11813 return qctx->result;