Lines Matching defs:client

70 #include <ns/client.h>
141 /*% Was the client already sent a response? */
161 client_trace(ns_client_t *client, int level, const char *message) {
162 if (client != NULL && client->query.qname != NULL) {
166 dns_name_format(client->query.qname, qbuf,
168 dns_rdatatype_format(client->query.qtype, tbuf,
172 "query client=%p thread=0x%" PRIxPTR
174 client, isc_thread_self(), qbuf, tbuf,
180 "query client=%p thread=0x%" PRIxPTR
182 client, isc_thread_self(), message);
185 #define CTRACE(l, m) client_trace(client, l, m)
186 #define CCTRACE(l, m) client_trace(qctx->client, l, m)
216 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
221 dns_dbversion_t *version, ns_client_t *client,
226 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level);
229 rpz_st_clear(ns_client_t *client);
232 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
246 acquire_recursionquota(ns_client_t *client);
249 release_recursionquota(ns_client_t *client);
328 * 1. Set up query context and other resources for a client
360 * otherwise go to 15 to clean up and return the delegation to the client.
364 * query_addauth()), then go to 15 to return NXDOMAIN to client.
369 * NOERROR/ANCOUNT=0 to client.
382 * return it to the client.
393 qctx_init(ns_client_t *client, dns_fetchresponse_t **respp,
406 query_setup(ns_client_t *client, dns_rdatatype_t qtype);
516 query_clear_stale(ns_client_t *client);
522 inc_stats(ns_client_t *client, isc_statscounter_t counter) {
523 dns_zone_t *zone = client->query.authzone;
529 ns_stats_increment(client->manager->sctx->nsstats, counter);
550 rdataset = ISC_LIST_HEAD(client->query.qname->list);
562 ns_client_log_flags(ns_client_t *client, unsigned int flags,
567 isc_buffer_putuint8(&b, WANTRECURSION(client) ? '+' : '-');
568 if (client->ednsversion >= 0) {
572 (unsigned char)client->ednsversion);
575 if (client->signer != NULL) {
578 if (TCP(client)) {
587 if (HAVECOOKIE(client)) {
589 } else if (WANTCOOKIE(client)) {
598 ns_client_log_ecs(ns_client_t *client, char *ecsbuf, size_t len) {
600 dns_ecs_format(&client->ecs, ecsbuf + 6, len - 6);
605 log_response(ns_client_t *client, dns_rcode_t rcode) {
620 dns_name_format(client->query.origqname, namebuf, sizeof(namebuf));
621 dns_rdataclass_format(client->message->rdclass, classbuf,
623 dns_rdatatype_format(client->query.qtype, typebuf, sizeof(typebuf));
627 isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
629 if (HAVEECS(client)) {
630 ns_client_log_ecs(client, ecsbuf, sizeof(ecsbuf));
633 ns_client_log_flags(client, client->message->flags, client->extflags,
635 ns_client_log(client, NS_LOGCATEGORY_RESPONSES, NS_LOGMODULE_QUERY,
638 client->message->counts[DNS_SECTION_ANSWER],
639 client->message->counts[DNS_SECTION_AUTHORITY],
640 client->message->counts[DNS_SECTION_ADDITIONAL], flagsbuf,
645 query_send(ns_client_t *client) {
648 if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) {
649 inc_stats(client, ns_statscounter_nonauthans);
651 inc_stats(client, ns_statscounter_authans);
654 if (client->message->rcode == dns_rcode_noerror) {
656 if (ISC_LIST_EMPTY(client->message->sections[answer])) {
657 if (client->query.isreferral) {
665 } else if (client->message->rcode == dns_rcode_nxdomain) {
667 } else if (client->message->rcode == dns_rcode_badcookie) {
673 inc_stats(client, counter);
674 ns_client_send(client);
676 if ((client->manager->sctx->options & NS_SERVER_LOGRESPONSES) != 0) {
677 log_response(client, client->message->rcode);
680 isc_nmhandle_detach(&client->reqhandle);
684 query_error(ns_client_t *client, isc_result_t result, int line) {
692 inc_stats(client, ns_statscounter_servfail);
695 inc_stats(client, ns_statscounter_formerr);
698 inc_stats(client, ns_statscounter_failure);
702 if ((client->manager->sctx->options & NS_SERVER_LOGQUERIES) != 0) {
706 log_queryerror(client, result, line, loglevel);
708 ns_client_error(client, result);
710 if (client->query.origqname != NULL &&
711 (client->manager->sctx->options & NS_SERVER_LOGRESPONSES) != 0)
713 log_response(client, rcode);
716 isc_nmhandle_detach(&client->reqhandle);
720 query_next(ns_client_t *client, isc_result_t result) {
722 inc_stats(client, ns_statscounter_duplicate);
724 inc_stats(client, ns_statscounter_dropped);
726 inc_stats(client, ns_statscounter_failure);
728 ns_client_drop(client, result);
729 isc_nmhandle_detach(&client->reqhandle);
733 query_freefreeversions(ns_client_t *client, bool everything) {
737 for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;
746 ISC_LIST_UNLINK(client->query.freeversions, dbversion,
748 isc_mem_put(client->manager->mctx, dbversion,
755 ns_query_cancel(ns_client_t *client) {
756 REQUIRE(NS_CLIENT_VALID(client));
758 LOCK(&client->query.fetchlock);
760 dns_fetch_t **fetchp = &client->query.recursions[i].fetch;
766 if (client->query.hookactx != NULL) {
767 client->query.hookactx->cancel(client->query.hookactx);
768 client->query.hookactx = NULL;
770 UNLOCK(&client->query.fetchlock);
774 query_reset(ns_client_t *client, bool everything) {
781 * Reset the query state of a client to its default state.
787 ns_query_cancel(client);
792 for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
798 ISC_LIST_INITANDAPPEND(client->query.freeversions, dbversion,
801 ISC_LIST_INIT(client->query.activeversions);
803 if (client->query.authdb != NULL) {
804 dns_db_detach(&client->query.authdb);
806 if (client->query.authzone != NULL) {
807 dns_zone_detach(&client->query.authzone);
810 if (client->query.dns64_aaaa != NULL) {
811 ns_client_putrdataset(client, &client->query.dns64_aaaa);
813 if (client->query.dns64_sigaaaa != NULL) {
814 ns_client_putrdataset(client, &client->query.dns64_sigaaaa);
816 if (client->query.dns64_aaaaok != NULL) {
817 isc_mem_cput(client->manager->mctx, client->query.dns64_aaaaok,
818 client->query.dns64_aaaaoklen, sizeof(bool));
819 client->query.dns64_aaaaok = NULL;
820 client->query.dns64_aaaaoklen = 0;
823 ns_client_putrdataset(client, &client->query.redirect.rdataset);
824 ns_client_putrdataset(client, &client->query.redirect.sigrdataset);
825 if (client->query.redirect.db != NULL) {
826 if (client->query.redirect.node != NULL) {
827 dns_db_detachnode(client->query.redirect.db,
828 &client->query.redirect.node);
830 dns_db_detach(&client->query.redirect.db);
832 if (client->query.redirect.zone != NULL) {
833 dns_zone_detach(&client->query.redirect.zone);
836 query_freefreeversions(client, everything);
838 for (dbuf = ISC_LIST_HEAD(client->query.namebufs); dbuf != NULL;
843 ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);
848 if (client->query.restarts > 0) {
850 * client->query.qname was dynamically allocated.
852 dns_message_puttempname(client->message, &client->query.qname);
854 client->query.qname = NULL;
855 client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
857 client->query.restarts = 0;
858 client->query.timerset = false;
859 if (client->query.rpz_st != NULL) {
860 rpz_st_clear(client);
862 INSIST(client->query.rpz_st->rpsdb == NULL);
863 isc_mem_put(client->manager->mctx, client->query.rpz_st,
864 sizeof(*client->query.rpz_st));
865 client->query.rpz_st = NULL;
868 client->query.origqname = NULL;
869 client->query.dboptions = 0;
870 client->query.fetchoptions = 0;
871 client->query.gluedb = NULL;
872 client->query.authdbset = false;
873 client->query.isreferral = false;
874 client->query.dns64_options = 0;
875 client->query.dns64_ttl = UINT32_MAX;
876 recparam_update(&client->query.recparam, 0, NULL, NULL);
877 client->query.root_key_sentinel_keyid = 0;
878 client->query.root_key_sentinel_is_ta = false;
879 client->query.root_key_sentinel_not_ta = false;
883 query_cleanup(ns_client_t *client) {
884 query_reset(client, false);
888 ns_query_free(ns_client_t *client) {
889 REQUIRE(NS_CLIENT_VALID(client));
891 query_reset(client, true);
895 ns_query_init(ns_client_t *client) {
896 REQUIRE(NS_CLIENT_VALID(client));
898 client->query = (ns_query_t){ 0 };
900 ISC_LIST_INIT(client->query.namebufs);
901 ISC_LIST_INIT(client->query.activeversions);
902 ISC_LIST_INIT(client->query.freeversions);
904 * This mutex is destroyed when the client is destroyed in
907 isc_mutex_init(&client->query.fetchlock);
908 client->query.redirect.fname =
909 dns_fixedname_initname(&client->query.redirect.fixed);
910 query_reset(client, false);
911 ns_client_newdbversion(client, 3);
912 ns_client_newnamebuf(client);
916 * Check if 'client' is allowed to query the cache of its associated view.
920 * The cache ACL is only evaluated once for each client and then the result is
921 * cached: if NS_QUERYATTR_CACHEACLOKVALID is set in client->query.attributes,
923 * also stored in client->query.attributes: if NS_QUERYATTR_CACHEACLOK is set,
924 * the client is allowed cache access.
928 *\li #ISC_R_SUCCESS 'client' is allowed to access cache
929 *\li #DNS_R_REFUSED 'client' is not allowed to access cache
932 query_checkcacheaccess(ns_client_t *client, const dns_name_t *name,
936 if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) == 0) {
954 result = ns_client_checkaclsilent(client, NULL,
955 client->view->cacheacl, true);
959 client, &client->destaddr,
960 client->view->cacheonacl, true);
966 client->query.attributes |= NS_QUERYATTR_CACHEACLOK;
971 client->view->rdclass, msg,
973 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
985 ns_client_extendederror(client, DNS_EDE_PROHIBITED,
990 client->view->rdclass, msg,
992 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1001 * NS_QUERYATTR_CACHEACLOK for this client from now on.
1003 client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
1006 return (client->query.attributes & NS_QUERYATTR_CACHEACLOK) != 0
1012 query_validatezonedb(ns_client_t *client, const dns_name_t *name,
1027 return query_checkcacheaccess(client, name, qtype, options);
1037 if (client->query.rpz_st == NULL &&
1038 !(WANTRECURSION(client) && RECURSIONOK(client)) &&
1039 client->query.authdbset && db != client->query.authdb)
1050 !RECURSIONOK(client))
1066 dbversion = ns_client_findversion(client, db);
1084 queryacl = client->view->queryacl;
1085 if ((client->query.attributes & NS_QUERYATTR_QUERYOKVALID) != 0)
1089 * NS_QUERYATTR_QUERYOK is set, then the client is
1094 if ((client->query.attributes & NS_QUERYATTR_QUERYOK) ==
1105 result = ns_client_checkaclsilent(client, NULL, queryacl, true);
1111 client->view->rdclass, msg,
1113 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1120 client->view->rdclass, msg,
1122 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1125 ns_client_extendederror(client, DNS_EDE_PROHIBITED,
1130 if (queryacl == client->view->queryacl) {
1137 client->query.attributes |= NS_QUERYATTR_QUERYOK;
1143 client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
1150 queryonacl = client->view->queryonacl;
1153 result = ns_client_checkaclsilent(client, &client->destaddr,
1156 ns_client_extendederror(client, DNS_EDE_PROHIBITED,
1160 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1180 query_getzonedb(ns_client_t *client, const dns_name_t *name,
1201 result = dns_view_findzone(client->view, name, ztoptions, &zone);
1214 result = query_validatezonedb(client, name, qtype, options, zone, db,
1242 rpz_log_rewrite(ns_client_t *client, bool disabled, dns_rpz_policy_t policy,
1260 ns_stats_increment(client->manager->sctx->nsstats,
1275 st = client->query.rpz_st;
1280 dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf));
1292 rdataset = ISC_LIST_HEAD(client->query.origqname->list);
1302 ns_client_log(client, log_cat, NS_LOGMODULE_QUERY, DNS_RPZ_INFO_LEVEL,
1310 rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name,
1343 dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf));
1353 ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY,
1360 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name,
1362 rpz_log_fail_helper(client, level, p_name, rpz_type, DNS_RPZ_TYPE_BAD,
1370 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type,
1380 result = query_getzonedb(client, p_name, dns_rdatatype_any, options,
1383 dns_rpz_st_t *st = client->query.rpz_st;
1392 dns_name_format(client->query.qname, qnamebuf,
1395 ns_client_log(client, DNS_LOGCATEGORY_RPZ,
1404 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type,
1411 * if the client is not allowed to use the cache.
1414 query_getcachedb(ns_client_t *client, const dns_name_t *name,
1422 if (!USECACHE(client)) {
1426 dns_db_attach(client->view->cachedb, &db);
1428 result = query_checkcacheaccess(client, name, qtype, options);
1443 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
1459 result = query_getzonedb(client, name, qtype, options, &zone, dbp,
1472 !ISC_LIST_EMPTY(client->view->dlz_searched))
1479 dns_clientinfo_init(&ci, client, NULL);
1480 dns_clientinfo_setecs(&ci, &client->ecs);
1483 tresult = dns_view_searchdlz(client->view, name, zonelabels,
1509 dbversion = ns_client_findversion(client, tdbp);
1537 result = query_getcachedb(client, name, qtype, dbp,
1546 query_isduplicate(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
1557 result = dns_message_findname(client->message, section, name,
1587 * 'client'. Called from query_additionalauth().
1611 ns_client_t *client, dns_dbnode_t **nodep,
1620 dns_clientinfo_init(&ci, client, NULL);
1628 client->query.dboptions, client->now, &node,
1687 ns_client_t *client = qctx->client;
1699 if (!client->query.authdbset || client->query.authdb == NULL) {
1703 dbversion = ns_client_findversion(client, client->query.authdb);
1708 dns_db_attach(client->query.authdb, &db);
1713 result = query_additionalauthfind(db, version, name, type, client,
1717 RECURSIONOK(client))
1726 result = query_getzonedb(client, name, type, options, &zone,
1736 client, &node, fname,
1757 ns_client_t *client = qctx->client;
1775 REQUIRE(NS_CLIENT_VALID(client));
1778 if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) {
1785 dns_clientinfo_init(&ci, client, NULL);
1802 dbuf = ns_client_getnamebuf(client);
1803 fname = ns_client_newname(client, dbuf, &b);
1804 rdataset = ns_client_newrdataset(client);
1805 if (WANTDNSSEC(client)) {
1806 sigrdataset = ns_client_newrdataset(client);
1814 client->query.qtype != dns_rdatatype_ns)
1837 result = query_getcachedb(client, name, qtype, &db, options);
1840 * Most likely the client isn't allowed to query the cache.
1848 sigrdataset = ns_client_newrdataset(client);
1853 client->query.dboptions | DNS_DBFIND_GLUEOK |
1855 client->now, &node, fname, &cm, &ci, rdataset,
1859 if (!WANTDNSSEC(client)) {
1860 ns_client_putrdataset(client, &sigrdataset);
1890 * case (identified by client->query.gluedb being set).
1893 if (client->query.gluedb == NULL) {
1900 if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) {
1904 dbversion = ns_client_findversion(client, client->query.gluedb);
1909 dns_db_attach(client->query.gluedb, &db);
1913 client->query.dboptions | DNS_DBFIND_GLUEOK,
1914 client->now, &node, fname, &cm, &ci, rdataset,
1927 ns_client_keepname(client, fname, dbuf);
1942 !query_isduplicate(client, fname, type, &mname))
1946 ns_client_releasename(client, &fname);
1980 rdataset = ns_client_newrdataset(client);
1986 } else if (WANTDNSSEC(client)) {
1987 sigrdataset = ns_client_newrdataset(client);
1989 if (query_isduplicate(client, fname, dns_rdatatype_a, NULL)) {
1993 0, client->now, rdataset,
2013 invalid = !validate(client, db, fname, rdataset,
2023 } else if (!query_isduplicate(client, fname,
2028 ns_client_releasename(client,
2043 ns_client_newrdataset(client);
2045 rdataset = ns_client_newrdataset(client);
2056 if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL))
2061 dns_rdatatype_aaaa, 0, client->now,
2082 invalid = !validate(client, db, fname, rdataset,
2093 } else if (!query_isduplicate(client, fname,
2099 ns_client_releasename(client,
2135 dns_message_addname(client->message, fname,
2145 if (client->additionaldepth++ < client->view->max_restarts) {
2149 client->additionaldepth--;
2159 ns_client_putrdataset(client, &rdataset);
2161 ns_client_putrdataset(client, &sigrdataset);
2164 ns_client_releasename(client, &fname);
2190 ns_client_t *client = qctx->client;
2191 dns_order_t *order = client->view->order;
2195 UNUSED(client);
2210 ns_client_t *client = qctx->client;
2215 if (NOADDITIONAL(client)) {
2223 client->query.gluedb != NULL && dns_db_iszone(client->query.gluedb))
2227 dbversion = ns_client_findversion(client, client->query.gluedb);
2233 client->message);
2254 ns_client_t *client = qctx->client;
2268 * To the current response for 'client', add the answer RRset
2277 result = dns_message_findname(client->message, section, name,
2287 ns_client_releasename(client, namep);
2302 ns_client_keepname(client, name, dbuf);
2304 dns_message_addname(client->message, name, section);
2310 ns_client_releasename(client, namep);
2317 client->query.attributes &= ~NS_QUERYATTR_SECURE;
2350 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name,
2362 dns_clientinfo_init(&ci, client, NULL);
2374 client->view->acceptexpired);
2376 (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, 0,
2378 (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, 0,
2390 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
2399 dns_clientinfo_init(&ci, client, NULL);
2410 client->now, keyrdataset, NULL);
2434 client->manager->mctx, keyp);
2452 dns_rdata_t *rdata, ns_client_t *client) {
2461 client->view->maxbits, client->manager->mctx,
2463 if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
2477 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
2496 if (!dns_resolver_algorithm_supported(client->view->resolver,
2506 if (!get_key(client, db, &rrsig, &keyrdataset, &key)) {
2509 if (verify(key, name, rdataset, &rdata, client)) {
2512 mark_secure(client, db, name, &rrsig, rdataset,
2526 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) {
2528 *rdataset = ns_client_newrdataset(client);
2535 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf,
2538 *dbuf = ns_client_getnamebuf(client);
2539 *fname = ns_client_newname(client, *dbuf, nbuf);
2544 free_fresp(ns_client_t *client, dns_fetchresponse_t **frespp) {
2559 ns_client_putrdataset(client, &fresp->rdataset);
2562 ns_client_putrdataset(client, &fresp->sigrdataset);
2570 recursionquotatype_attach(ns_client_t *client, bool soft_limit) {
2574 result = isc_quota_acquire(&client->manager->sctx->recursionquota);
2588 isc_quota_release(&client->manager->sctx->recursionquota);
2594 recurscount = ns_stats_increment(client->manager->sctx->nsstats,
2597 ns_stats_update_if_greater(client->manager->sctx->nsstats,
2605 recursionquotatype_attach_hard(ns_client_t *client) {
2606 return recursionquotatype_attach(client, false);
2610 recursionquotatype_attach_soft(ns_client_t *client) {
2611 return recursionquotatype_attach(client, true);
2615 recursionquotatype_detach(ns_client_t *client) {
2616 isc_quota_release(&client->manager->sctx->recursionquota);
2617 ns_stats_decrement(client->manager->sctx->nsstats,
2622 stale_refresh_aftermath(ns_client_t *client, isc_result_t result) {
2654 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
2655 dns_rdatatype_format(client->query.qtype, typebuf,
2657 ns_client_log(client, NS_LOGCATEGORY_SERVE_STALE,
2668 client->now = isc_stdtime_now();
2669 client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
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);
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,
2706 ns_client_t *client = resp->arg;
2711 REQUIRE(NS_CLIENT_VALID(client));
2715 handlep = &client->query.recursions[recursion_type].handle;
2716 fetchp = &client->query.recursions[recursion_type].fetch;
2719 LOCK(&client->query.fetchlock);
2724 UNLOCK(&client->query.fetchlock);
2728 stale_refresh_aftermath(client, result);
2731 recursionquotatype_detach(client);
2732 free_fresp(client, &resp);
2754 * associated with 'client'. If the recursive clients quota (or even soft
2760 fetch_and_forget(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t qtype,
2770 result = recursionquotatype_attach_hard(client);
2775 tmprdataset = ns_client_newrdataset(client);
2777 if (!TCP(client)) {
2778 peeraddr = &client->peeraddr;
2785 options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
2789 options = client->query.fetchoptions;
2793 options = client->query.fetchoptions;
2800 handlep = &client->query.recursions[recursion_type].handle;
2801 fetchp = &client->query.recursions[recursion_type].fetch;
2803 isc_nmhandle_attach(client->handle, handlep);
2805 client->view->resolver, qname, qtype, NULL, NULL, NULL,
2806 peeraddr, client->message->id, options, 0, NULL,
2807 client->manager->loop, cb, client, tmprdataset, NULL, fetchp);
2809 ns_client_putrdataset(client, &tmprdataset);
2811 recursionquotatype_detach(client);
2816 query_prefetch(ns_client_t *client, dns_name_t *qname,
2820 if (FETCH_RECTYPE_PREFETCH(client) != NULL ||
2821 client->view->prefetch_trigger == 0U ||
2822 rdataset->ttl > client->view->prefetch_trigger ||
2828 fetch_and_forget(client, qname, rdataset->type, RECTYPE_PREFETCH);
2831 ns_stats_increment(client->manager->sctx->nsstats,
2836 query_stale_refresh(ns_client_t *client) {
2841 if (FETCH_RECTYPE_STALE_REFRESH(client) != NULL) {
2845 client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT |
2849 if (client->query.origqname != NULL) {
2850 qname = client->query.origqname;
2852 qname = client->query.qname;
2855 fetch_and_forget(client, qname, client->query.qtype,
2886 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) {
2892 *rdatasetp = ns_client_newrdataset(client);
2900 rpz_st_clear(ns_client_t *client) {
2901 dns_rpz_st_t *st = client->query.rpz_st;
2906 ns_client_putrdataset(client, &st->m.rdataset);
2912 ns_client_putrdataset(client, &st->r.ns_rdataset);
2915 ns_client_putrdataset(client, &st->r.r_rdataset);
2920 ns_client_putrdataset(client, &st->q.rdataset);
2923 ns_client_putrdataset(client, &st->q.sigrdataset);
2934 rpz_get_zbits(ns_client_t *client, dns_rdatatype_t ip_type,
2939 REQUIRE(client != NULL);
2940 REQUIRE(client->query.rpz_st != NULL);
2942 st = client->query.rpz_st;
3006 * If the client wants recursion, allow only compatible policies.
3008 if (!RECURSIONOK(client)) {
3016 query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) {
3019 if (FETCH_RECTYPE_RPZ(client) != NULL) {
3023 fetch_and_forget(client, qname, type, RECTYPE_RPZ);
3027 * Get an NS, A, or AAAA rrset related to the response for the client
3031 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type,
3046 st = client->query.rpz_st;
3055 ns_client_putrdataset(client, rdatasetp);
3061 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
3069 result = rpz_ready(client, rdatasetp);
3081 result = query_getdb(client, name, type,
3085 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
3101 dns_clientinfo_init(&ci, client, NULL);
3102 result = dns_db_findext(*dbp, name, version, type, options, client->now,
3104 if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
3111 dns_db_attach(client->view->cachedb, dbp);
3113 client->now, &node, found, &cm, &ci,
3125 } else if (!client->view->rpzs->p.nsip_wait_recurse ||
3126 (!client->view->rpzs->p.nsdname_wait_recurse &&
3129 query_rpzfetch(client, name, type);
3133 result = ns_query_recurse(client, type, st->r_name,
3149 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name, dns_rpz_zone_t *rpz,
3203 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix,
3211 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix,
3221 * The self-name (usually the client qname or an NS name) is compared with
3228 * If it is best, the caller records it in client->query.rpz_st->m.
3231 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype,
3248 dns_clientinfo_init(&ci, client, NULL);
3255 result = rpz_ready(client, rdatasetp);
3261 result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp);
3268 client->now, nodep, found, &cm, &ci, *rdatasetp,
3280 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name,
3287 !ISC_LIST_EMPTY(client->view->dns64))
3315 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
3337 qtype, 0, client->now,
3381 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, "",
3428 dnsrps_ck(librpz_emsg_t *emsg, ns_client_t *client, dns_rpsdb_t *rpsdb,
3462 dns_name_fromregion(client->query.rpz_st->p_name, &region);
3463 rpz_log_rewrite(client, true, dns_dnsrps_2policy(rpsdb->result.zpolicy),
3465 client->query.rpz_st->p_name, NULL,
3480 dnsrps_set_p(librpz_emsg_t *emsg, ns_client_t *client, dns_rpz_st_t *st,
3524 result = rpz_ready(client, p_rdatasetp);
3582 rpz_save_p(st, client->view->rpzs->zones[rpsdb->result.cznum],
3592 dnsrps_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
3604 st = client->query.rpz_st;
3607 result = rpz_ready(client, p_rdatasetp);
3638 (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0)
3640 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
3650 dnsrps_rewrite_name(ns_client_t *client, dns_name_t *trig_name, bool recursed,
3662 st = client->query.rpz_st;
3665 result = rpz_ready(client, p_rdatasetp);
3687 (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0)
3689 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
3703 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr,
3722 rpzs = client->view->rpzs;
3723 st = client->query.rpz_st;
3726 return dnsrps_rewrite_ip(client, netaddr, rpz_type,
3768 result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name);
3772 result = rpz_find_p(client, ip_name, qtype, p_name, rpz,
3800 * client-IP over QNAME over IP over NSDNAME over NSIP,
3836 rpz_log_rewrite(client, true, policy, rpz_type, p_zone,
3850 rpz_rewrite_ip_rrset(ns_client_t *client, dns_name_t *name,
3860 unsigned int options = client->query.dboptions | DNS_DBFIND_GLUEOK;
3866 zbits = rpz_get_zbits(client, ip_type, rpz_type);
3874 result = rpz_rrset_find(client, name, ip_type, options,
3896 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name,
3901 if (client->query.rpz_st->m.policy !=
3904 client->query.rpz_st->m.policy =
3906 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name,
3922 options = client->query.dboptions;
3924 options = client->query.dboptions | DNS_DBFIND_GLUEOK;
3952 result = rpz_rewrite_ip(client, &netaddr, qtype,
3959 client->query.rpz_st->m.policy == DNS_RPZ_POLICY_MISS);
3969 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name,
3980 st = client->query.rpz_st;
3993 client, name, qtype, rpz_type, dns_rdatatype_a, &ip_db,
4009 result = rpz_rewrite_ip_rrset(client, name, qtype, rpz_type,
4017 ns_client_putrdataset(client, &p_rdataset);
4025 * in client->query.rpz_st.
4029 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name,
4053 rpzs = client->view->rpzs;
4054 st = client->query.rpz_st;
4058 return dnsrps_rewrite_name(client, trig_name, recursed,
4063 zbits = rpz_get_zbits(client, qtype, rpz_type);
4117 result = rpz_get_p_name(client, p_name, rpz, rpz_type,
4122 result = rpz_find_p(client, trig_name, qtype, p_name, rpz,
4145 * client-IP over QNAME over IP over NSDNAME over NSIP,
4176 rpz_log_rewrite(client, true, policy, rpz_type, p_zone,
4187 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname,
4193 st = client->query.rpz_st;
4196 rpz_log_fail_helper(client, level, nsname, DNS_RPZ_TYPE_NSIP,
4221 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
4241 rpzs = client->view->rpzs;
4242 st = client->query.rpz_st;
4250 if (RECURSING(client)) {
4256 (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) ||
4257 !rpz_ck_dnssec(client, qresult, ordataset, osigset))
4272 st = isc_mem_get(client->manager->mctx, sizeof(*st));
4290 client->query.rpz_st = st;
4298 &emsg, st, rpzs, client->query.qname,
4299 client->manager->mctx, RECURSIONOK(client));
4301 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
4338 if (RECURSIONOK(client)) {
4348 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, NULL,
4353 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, NULL,
4385 * Check once for triggers for the client IP address.
4388 zbits = rpz_get_zbits(client, dns_rdatatype_none,
4393 &client->peeraddr);
4394 result = rpz_rewrite_ip(client, &netaddr, qtype,
4410 result = rpz_rewrite_name(client, client->query.qname,
4421 st->r.label = dns_name_countlabels(client->query.qname);
4428 * client-IP trigger before recursion.
4458 rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0)
4460 result = rpz_rewrite_ip_rrsets(client, client->query.qname,
4478 if (rpz_get_zbits(client, dns_rdatatype_any, DNS_RPZ_TYPE_NSDNAME) ==
4480 rpz_get_zbits(client, dns_rdatatype_any, DNS_RPZ_TYPE_NSIP) == 0)
4487 dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef));
4488 options = client->query.dboptions | DNS_DBFIND_GLUEOK;
4494 if (st->r.label == dns_name_countlabels(client->query.qname)) {
4495 nsname = client->query.qname;
4498 dns_name_split(client->query.qname, st->r.label, NULL,
4505 result = rpz_rrset_find(client, nsname,
4540 rpz_rewrite_ns_skip(client, nsname, result, 0,
4546 rpz_rewrite_ns_skip(client, nsname, result,
4551 rpz_rewrite_ns_skip(client, nsname, result,
4585 client, &ns.name, qtype,
4597 result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype,
4615 options = client->query.dboptions;
4617 options = client->query.dboptions | DNS_DBFIND_GLUEOK;
4621 if (rpz_get_zbits(client, dns_rdatatype_any,
4623 rpz_get_zbits(client, dns_rdatatype_any,
4638 !dnsrps_set_p(&emsg, client, st, qtype, &rdataset,
4641 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL,
4659 rpz_log_rewrite(client, false, st->m.policy, st->m.type,
4670 ns_client_putrdataset(client, &rdataset);
4680 * by the client in DNSSEC or a lack of signatures.
4683 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult,
4693 if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client)) {
4839 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) {
4866 ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
4881 dns_dbversion_t *version, ns_client_t *client,
4910 dns_clientinfo_init(&ci, client, NULL);
4928 dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3;
4930 dns_rdatatype_nsec3, dboptions, client->now,
4954 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
4960 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
4968 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC,
5025 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
5028 dns_aclenv_t *env = client->manager->aclenv;
5029 dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
5034 INSIST(client->query.dns64_aaaaok == NULL);
5035 INSIST(client->query.dns64_aaaaoklen == 0);
5036 INSIST(client->query.dns64_aaaa == NULL);
5037 INSIST(client->query.dns64_sigaaaa == NULL);
5043 if (RECURSIONOK(client)) {
5047 if (WANTDNSSEC(client) && sigrdataset != NULL &&
5054 aaaaok = isc_mem_cget(client->manager->mctx, count, sizeof(bool));
5056 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
5057 if (dns_dns64_aaaaok(dns64, &netaddr, client->signer, env, flags,
5062 SAVE(client->query.dns64_aaaaok, aaaaok);
5063 client->query.dns64_aaaaoklen = count;
5068 isc_mem_cput(client->manager->mctx, aaaaok, count,
5074 isc_mem_cput(client->manager->mctx, aaaaok, count,
5085 * Only perform the update if the client is in the allow query acl and
5089 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
5105 if (client->view->redirect == NULL) {
5113 dns_clientinfo_init(&ci, client, NULL);
5114 dns_clientinfo_setecs(&ci, &client->ecs);
5116 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
5121 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
5150 client, NULL, dns_zone_getqueryacl(client->view->redirect),
5156 result = dns_zone_getdb(client->view->redirect, &db);
5161 dbversion = ns_client_findversion(client, db);
5170 result = dns_db_findext(db, client->query.qname, dbversion->version,
5171 qtype, DNS_DBFIND_NOZONECUT, client->now, &node,
5212 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
5219 redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
5239 if (client->view->redirectzone == NULL) {
5243 if (dns_name_issubdomain(name, client->view->redirectzone)) {
5251 dns_clientinfo_init(&ci, client, NULL);
5252 dns_clientinfo_setecs(&ci, &client->ecs);
5254 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
5259 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
5288 labels = dns_name_countlabels(client->query.qname);
5293 dns_name_getlabelsequence(client->query.qname, 0, labels - 1,
5296 client->view->redirectzone,
5302 dns_name_copy(redirectname, client->view->redirectzone);
5305 result = query_getdb(client, redirectname, qtype,
5319 client->now, &node, found, &cm, &ci, &trdataset,
5343 if (!REDIRECT(client)) {
5344 result = ns_query_recurse(client, qtype, redirectname,
5347 client->query.attributes |=
5349 client->query.attributes |=
5370 dns_name_split(found, dns_name_countlabels(client->view->redirectzone),
5398 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
5406 * first handling a client query, and by query_resume() when
5413 qctx_init(ns_client_t *client, dns_fetchresponse_t **frespp,
5416 REQUIRE(client != NULL);
5421 qctx->client = client;
5423 dns_view_attach(client->view, &qctx->view);
5474 ns_client_putrdataset(qctx->client, &qctx->rdataset);
5478 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
5482 ns_client_releasename(qctx->client, &qctx->fname);
5495 ns_client_putrdataset(qctx->client, &qctx->zsigrdataset);
5496 ns_client_putrdataset(qctx->client, &qctx->zrdataset);
5497 ns_client_releasename(qctx->client, &qctx->zfname);
5504 free_fresp(qctx->client, &qctx->fresp);
5528 * Note: this function doesn't attach to the client's handle. It's the caller's
5536 /* Then "move" pointers (except client and view) */
5563 * the client request or a return from recursion.
5571 if (qctx->client->query.origqname != NULL) {
5572 dns_name_format(qctx->client->query.origqname, qbuf,
5579 "client attr:0x%x, query attr:0x%X, restarts:%u, "
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);
5593 * Set up query processing for the current query of 'client'.
5604 query_setup(ns_client_t *client, dns_rdatatype_t qtype) {
5608 qctx_init(client, NULL, qtype, &qctx);
5642 qctx->client->query.root_key_sentinel_keyid = v;
5654 const char *ndata = (const char *)qctx->client->query.qname->ndata;
5656 if (qctx->client->query.qname->length > 30 && ndata[0] == 29 &&
5662 qctx->client->query.root_key_sentinel_is_ta = true;
5668 ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
5671 } else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 &&
5677 qctx->client->query.root_key_sentinel_not_ta = true;
5683 ns_client_log(qctx->client, NS_LOGCATEGORY_TAT,
5690 * Starting point for a client query or a chaining query.
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;
5726 !dns_rdata_checkowner(qctx->client->query.qname,
5727 qctx->client->message->rdclass, qctx->qtype,
5734 dns_name_format(qctx->client->query.qname, namebuf,
5737 dns_rdataclass_format(qctx->client->message->rdclass, classbuf,
5739 ns_client_log(qctx->client, DNS_LOGCATEGORY_SECURITY,
5751 qctx->client->query.restarts == 0 &&
5754 (qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0)
5765 !dns_name_equal(qctx->client->query.qname, dns_rootname))
5776 result = query_getdb(qctx->client, qctx->client->query.qname,
5780 qctx->qtype == dns_rdatatype_ds && !RECURSIONOK(qctx->client) &&
5796 qctx->client, qctx->client->query.qname, qctx->qtype,
5804 ns_client_putrdataset(qctx->client, &qctx->rdataset);
5837 if (WANTRECURSION(qctx->client)) {
5838 inc_stats(qctx->client,
5841 inc_stats(qctx->client,
5844 if (!PARTIALANSWER(qctx->client)) {
5878 if (qctx->fresp == NULL && qctx->client->query.restarts == 0) {
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);
5905 * stale-answer-client-timeout is zero, then we can promptly
5927 ns_client_t *client = qctx->client;
5928 isc_nmhandle_t *handle = client->restarthandle;
5930 client->restarthandle = NULL;
5937 isc_mem_put(client->manager->mctx, qctx, sizeof(*qctx));
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) &&
5960 qctx->sigrdataset = ns_client_newrdataset(qctx->client);
5968 * client this stale answer.
6015 dns_clientinfo_init(&ci, qctx->client, NULL);
6016 if (HAVEECS(qctx->client)) {
6017 dns_clientinfo_setecs(&ci, &qctx->client->ecs);
6033 rpzqname = qctx->client->query.rpz_st->p_name;
6035 rpzqname = qctx->client->query.qname;
6045 qctx->client->query.dboptions |= DNS_DBFIND_STALETIMEOUT;
6048 dboptions = qctx->client->query.dboptions;
6055 (void)dns_db_getservestalerefresh(qctx->client->view->cachedb,
6058 dns_view_staleanswerenabled(qctx->client->view))
6064 dboptions, qctx->client->now, &qctx->node,
6072 dns_name_copy(qctx->client->query.qname, qctx->fname);
6102 * This can happen if 'stale-answer-client-timeout' is enabled.
6104 * If a stale answer is found, send it to the client, and try to refresh
6117 dns_name_format(qctx->client->query.qname, namebuf,
6121 inc_stats(qctx->client, ns_statscounter_trystale);
6136 inc_stats(qctx->client, ns_statscounter_usedstale);
6150 ns_client_extendederror(qctx->client, ede,
6175 qctx->client, ede,
6194 dns_db_attach(qctx->client->view->cachedb,
6196 qctx->client->query.dboptions &=
6199 if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL)
6203 qctx->client));
6221 qctx->client, ede,
6233 * Mark RRsets that we are adding to the client message on a
6234 * lookup during 'stale-answer-client-timeout', so we can
6237 qctx->client->query.attributes |= NS_QUERYATTR_STALEOK;
6293 * Clear any rdatasets from the client's message that were added on a lookup
6294 * due to a client timeout.
6297 query_clear_stale(ns_client_t *client) {
6298 message_clearrdataset(client->message, DNS_RDATASETATTR_STALE_ADDED);
6303 * client timeout is triggered. If the query has timed out or been cancelled
6304 * or the system is shutting down, clean up and exit. If a client timeout is
6311 ns_client_t *client = resp->arg;
6319 REQUIRE(NS_CLIENT_VALID(client));
6320 REQUIRE(RECURSING(client));
6326 * that a lookup due to stale-answer-client-timeout may have set.
6328 if (client->view->cachedb != NULL && client->view->recursion) {
6329 client->query.attributes |= NS_QUERYATTR_RECURSIONOK;
6331 client->query.dboptions &= ~DNS_DBFIND_STALETIMEOUT;
6333 LOCK(&client->query.fetchlock);
6334 INSIST(FETCH_RECTYPE_NORMAL(client) == resp->fetch ||
6335 FETCH_RECTYPE_NORMAL(client) == NULL);
6336 if (FETCH_RECTYPE_NORMAL(client) != NULL) {
6340 INSIST(FETCH_RECTYPE_NORMAL(client) == resp->fetch);
6341 FETCH_RECTYPE_NORMAL(client) = NULL;
6344 * Update client->now.
6346 client->now = isc_stdtime_now();
6354 UNLOCK(&client->query.fetchlock);
6362 release_recursionquota(client);
6364 isc_nmhandle_detach(&HANDLE_RECTYPE_NORMAL(client));
6366 client->query.attributes &= ~NS_QUERYATTR_RECURSING;
6367 client->state = NS_CLIENTSTATE_WORKING;
6374 qctx_init(client, &resp, 0, &qctx);
6381 * client, which we still need for a moment.
6386 * Return an error to the client.
6389 query_error(client, DNS_R_SERVFAIL, __LINE__);
6393 * service the client, then detach the client object.
6466 recursionquota_log(ns_client_t *client, atomic_uint_fast32_t *last_log_time,
6474 ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY,
6482 * Acquire recursion quota before making the current client "recursing".
6485 acquire_recursionquota(ns_client_t *client) {
6488 result = recursionquotatype_attach_soft(client);
6491 recursionquota_log(client, &last_soft,
6494 &client->manager->sctx->recursionquota);
6495 ns_client_killoldestquery(client);
6500 recursionquota_log(client, &last_hard,
6502 &client->manager->sctx->recursionquota);
6503 ns_client_killoldestquery(client);
6509 dns_message_clonebuffer(client->message);
6510 ns_client_recursing(client);
6516 * Release recursion quota and remove the client from the "recursing" list.
6519 release_recursionquota(ns_client_t *client) {
6520 recursionquotatype_detach(client);
6522 LOCK(&client->manager->reclock);
6523 if (ISC_LINK_LINKED(client, rlink)) {
6524 ISC_LIST_UNLINK(client->manager->recursing, client, rlink);
6526 UNLOCK(&client->manager->reclock);
6530 ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
6543 if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) {
6544 ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY,
6549 recparam_update(&client->query.recparam, qtype, qname, qdomain);
6552 inc_stats(client, ns_statscounter_recursion);
6555 result = acquire_recursionquota(client);
6564 REQUIRE(FETCH_RECTYPE_NORMAL(client) == NULL);
6566 rdataset = ns_client_newrdataset(client);
6568 if (WANTDNSSEC(client)) {
6569 sigrdataset = ns_client_newrdataset(client);
6574 if (!client->query.timerset) {
6575 ns_client_settimeout(client, 60);
6578 if (!TCP(client)) {
6579 peeraddr = &client->peeraddr;
6582 isc_nmhandle_attach(client->handle, &HANDLE_RECTYPE_NORMAL(client));
6584 client->view->resolver, qname, qtype, qdomain, nameservers,
6585 NULL, peeraddr, client->message->id, client->query.fetchoptions,
6586 0, NULL, client->manager->loop, fetch_callback, client,
6587 rdataset, sigrdataset, &FETCH_RECTYPE_NORMAL(client));
6589 release_recursionquota(client);
6591 ns_client_putrdataset(client, &rdataset);
6593 ns_client_putrdataset(client, &sigrdataset);
6596 isc_nmhandle_detach(&HANDLE_RECTYPE_NORMAL(client));
6600 * We're now waiting for a fetch event. A client which is
6629 qctx->rpz_st = qctx->client->query.rpz_st;
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,
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);
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);
6700 qctx->client->query.redirect.authoritative;
6705 ns_client_putrdataset(qctx->client, &qctx->fresp->rdataset);
6706 ns_client_putrdataset(qctx->client, &qctx->fresp->sigrdataset);
6735 if (DNS64(qctx->client)) {
6736 qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64;
6740 if (DNS64EXCLUDE(qctx->client)) {
6741 qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
6752 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
6767 qctx->dbuf = ns_client_getnamebuf(qctx->client);
6768 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
6774 } else if (REDIRECT(qctx->client)) {
6775 tname = qctx->client->query.redirect.fname;
6787 free_fresp(qctx->client, &qctx->fresp);
6788 } else if (REDIRECT(qctx->client)) {
6789 result = qctx->client->query.redirect.result;
6806 ns_client_t *client = rev->arg;
6812 REQUIRE(NS_CLIENT_VALID(client));
6814 LOCK(&client->query.fetchlock);
6815 if (client->query.hookactx != NULL) {
6816 INSIST(rev->ctx == client->query.hookactx);
6817 client->query.hookactx = NULL;
6819 client->now = isc_stdtime_now();
6823 UNLOCK(&client->query.fetchlock);
6826 release_recursionquota(client);
6833 isc_nmhandle_detach(&HANDLE_RECTYPE_HOOK(client));
6835 client->state = NS_CLIENTSTATE_WORKING;
6843 query_error(client, DNS_R_SERVFAIL, __LINE__);
6853 * As we're almost done with this client, make sure any internal
6861 query_setup(client, qctx->qtype);
6935 isc_mem_put(client->manager->mctx, qctx, sizeof(*qctx));
6942 ns_client_t *client = qctx->client;
6947 REQUIRE(NS_CLIENT_VALID(client));
6948 REQUIRE(client->query.hookactx == NULL);
6949 REQUIRE(FETCH_RECTYPE_NORMAL(client) == NULL);
6951 result = acquire_recursionquota(client);
6956 saved_qctx = isc_mem_get(client->manager->mctx, sizeof(*saved_qctx));
6958 result = runasync(saved_qctx, client->manager->mctx, arg,
6959 client->manager->loop, query_hookresume, client,
6960 &client->query.hookactx);
6974 * the client task or pausing it.
6976 isc_nmhandle_attach(client->handle, &HANDLE_RECTYPE_HOOK(client));
6980 release_recursionquota(client);
6987 query_error(client, DNS_R_SERVFAIL, __LINE__);
6999 isc_mem_put(client->manager->mctx, saved_qctx,
7021 if (!RECURSIONOK(qctx->client)) {
7027 if (qctx->client->manager->sctx->fuzztype == isc_fuzz_resolver) {
7033 qctx->view->failcache, qctx->client->query.qname,
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,
7053 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
7062 qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
7079 isc_netaddr_fromsockaddr(&peer, &qctx->client->peeraddr);
7084 dns_name_format(qctx->client->query.qname, qnamebuf, sizeof(qnamebuf));
7095 * Rate limit these responses to this client.
7111 qctx->client, DNS_LOGCATEGORY_RRL, NS_LOGMODULE_QUERY,
7116 qctx->client->view->rrl, HAVECOOKIE(qctx->client),
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) &&
7130 (result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) &&
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;
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,
7234 inc_stats(qctx->client,
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
7280 rresult = rpz_rewrite(qctx->client, qctx->qtype, result, qctx->resuming,
7282 qctx->rpz_st = qctx->client->query.rpz_st;
7294 INSIST(!RECURSING(qctx->client));
7305 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
7319 !TCP(qctx->client)) &&
7328 dns_name_copy(qctx->client->query.qname, qctx->fname);
7331 ns_client_putrdataset(qctx->client, &qctx->rdataset);
7357 qctx->client->message->flags |= DNS_MESSAGEFLAG_TC;
7361 qctx->client->message->rcode =
7364 rpz_log_rewrite(qctx->client, false,
7372 rpz_log_rewrite(qctx->client, false,
7451 ns_client_extendederror(qctx->client,
7459 qctx->client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
7461 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD;
7462 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
7465 rpz_log_rewrite(qctx->client, false, qctx->rpz_st->m.policy,
7482 ns_client_t *client;
7487 REQUIRE(qctx != NULL && qctx->client != NULL);
7489 client = qctx->client;
7496 dns_name_split(client->query.qname, 1,
7505 client->message->rcode = dns_rcode_yxdomain;
7513 ns_client_keepname(client, qctx->fname, qctx->dbuf);
7516 rpz_log_rewrite(client, false, qctx->rpz_st->m.policy,
7521 ns_client_qnamereplace(client, qctx->fname);
7527 client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
7535 * with a key id that matches qctx->client->query.root_key_sentinel_keyid.
7544 dns_keytag_t sentinel = qctx->client->query.root_key_sentinel_keyid;
7601 if (!qctx->client->query.root_key_sentinel_is_ta &&
7602 !qctx->client->query.root_key_sentinel_not_ta)
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;
7648 if ((qctx->client->query.dboptions & DNS_DBFIND_STALEOK) != 0) {
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,
7681 qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
7682 if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL) {
7684 &FETCH_RECTYPE_NORMAL(qctx->client));
7692 qctx->client->query.dboptions |= DNS_DBFIND_STALESTART;
7717 if (!dns_name_equal(qctx->client->query.qname, dns_rootname)) {
7725 if (RECURSING(qctx->client) && result == DNS_R_DISALLOWED) {
7729 * "stale-answer-client-timeout" lookup. In this case,
7749 qctx->client->attributes |= NS_CLIENTATTR_NOSETFC;
7817 qctx->client->rcode_override = dns_rcode_servfail;
7829 ns_client_t *client = qctx->client;
7841 dbuf = ns_client_getnamebuf(client);
7842 fname = ns_client_newname(client, dbuf, &b);
7843 neg = ns_client_newrdataset(client);
7844 negsig = ns_client_newrdataset(client);
7857 dbuf = ns_client_getnamebuf(client);
7858 fname = ns_client_newname(client, dbuf, &b);
7862 neg = ns_client_newrdataset(client);
7868 negsig = ns_client_newrdataset(client);
7881 ns_client_putrdataset(client, &neg);
7884 ns_client_putrdataset(client, &negsig);
7887 ns_client_releasename(client, &fname);
7926 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
7958 } else if (qctx->view->minimal_any && !TCP(qctx->client) &&
7959 !WANTDNSSEC(qctx->client) &&
7967 } else if (qctx->view->minimal_any && !TCP(qctx->client) &&
7978 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client))
7985 qctx->rpz_st = qctx->client->query.rpz_st;
7992 if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
7996 query_prefetch(qctx->client, name,
8028 ns_client_putrdataset(qctx->client,
8032 qctx->rdataset = ns_client_newrdataset(qctx->client);
8062 dns_message_puttempname(qctx->client->message, &qctx->fname);
8079 qctx->client->attributes &= ~NS_CLIENTATTR_RA;
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);
8123 qctx->client->query.restarts != 0 ||
8124 (qctx->client->attributes & NS_CLIENTATTR_WANTEXPIRE) == 0)
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;
8156 qctx->client->expire = soa.expire;
8157 qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE;
8179 * lookup due to stale-answer-client-timeout. Do not clear if we
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;
8199 dns_message_puttemprdataset(qctx->client->message,
8224 } else if (qctx->client->query.dns64_aaaaok != NULL) {
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,
8234 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
8261 INSIST(qctx->client->query.dns64_aaaaok == NULL);
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);
8292 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
8306 if (dns_name_equal(qctx->client->query.qname,
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);
8337 * the message to be sent to the client already contains an RRset with
8341 * to be the final answer to the client's query, but we have no way of
8357 ns_client_t *client = qctx->client;
8358 dns_aclenv_t *env = client->manager->aclenv;
8368 dns_view_t *view = client->view;
8375 * To the current response for 'qctx->client', add the answer RRset
8397 client->message, section, name, dns_rdatatype_aaaa,
8407 ns_client_releasename(client, &qctx->fname);
8415 ns_client_keepname(client, name, qctx->dbuf);
8417 dns_message_addname(client->message, name, section);
8423 ns_client_releasename(client, &qctx->fname);
8428 client->query.attributes &= ~NS_QUERYATTR_SECURE;
8431 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
8433 isc_buffer_allocate(client->manager->mctx, &buffer,
8436 dns_message_gettemprdataset(client->message, &dns64_rdataset);
8437 dns_message_gettemprdatalist(client->message, &dns64_rdatalist);
8442 if (client->query.dns64_ttl != UINT32_MAX) {
8444 client->query.dns64_ttl);
8449 if (RECURSIONOK(client)) {
8457 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
8467 for (dns64 = ISC_LIST_HEAD(client->view->dns64); dns64 != NULL;
8474 client->signer, env, flags,
8483 dns_message_gettemprdata(client->message, &dns64_rdata);
8503 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
8511 dns_message_takebuffer(client->message, &buffer);
8512 inc_stats(client, ns_statscounter_dns64);
8521 dns_message_puttemprdataset(client->message, &dns64_rdataset);
8531 dns_message_puttemprdata(client->message, &dns64_rdata);
8533 dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
8542 ns_client_t *client = qctx->client;
8556 INSIST(client->query.dns64_aaaaok != NULL);
8557 INSIST(client->query.dns64_aaaaoklen ==
8567 client->message, section, name, dns_rdatatype_aaaa,
8577 ns_client_releasename(client, &qctx->fname);
8586 ns_client_releasename(client, &qctx->fname);
8592 client->query.attributes &= ~NS_QUERYATTR_SECURE;
8595 isc_buffer_allocate(client->manager->mctx, &buffer,
8597 dns_message_gettemprdataset(client->message, &myrdataset);
8598 dns_message_gettemprdatalist(client->message, &myrdatalist);
8610 if (!client->query.dns64_aaaaok[i++]) {
8618 dns_message_gettemprdata(client->message, &myrdata);
8632 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
8635 ns_client_keepname(client, name, qctx->dbuf);
8637 dns_message_addname(client->message, name, section);
8647 dns_message_takebuffer(client->message, &buffer);
8655 dns_message_puttemprdataset(client->message, &myrdataset);
8664 dns_message_puttemprdata(client->message, &myrdata);
8666 dns_message_puttemprdatalist(client->message, &myrdatalist);
8670 ns_client_releasename(client, &name);
8704 dns_clientinfo_init(&ci, qctx->client, NULL);
8708 dns_rdatatype_ns, 0, qctx->client->now,
8726 if (RECURSIONOK(qctx->client)) {
8727 INSIST(!REDIRECT(qctx->client));
8728 result = ns_query_recurse(qctx->client, qctx->qtype,
8729 qctx->client->query.qname,
8733 qctx->client->query.attributes |=
8737 qctx->client->query.attributes |=
8741 qctx->client->query.attributes |=
8772 * to the client.
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) {
8810 dns_db_detach(&qctx->client->query.gluedb);
8828 * delegation to the client and call ns_query_done().
8840 if (!RECURSIONOK(qctx->client) &&
8847 result = query_getzonedb(qctx->client,
8848 qctx->client->query.qname, qctx->qtype,
8859 ns_client_putrdataset(qctx->client, &qctx->rdataset);
8861 ns_client_putrdataset(qctx->client,
8865 ns_client_releasename(qctx->client,
8887 if (USECACHE(qctx->client) &&
8888 (RECURSIONOK(qctx->client) ||
8901 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
8926 * client and call ns_query_done().
8962 ns_client_releasename(qctx->client, &qctx->fname);
8971 ns_client_putrdataset(qctx->client, &qctx->rdataset);
8973 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
9005 dns_name_t *qname = qctx->client->query.qname;
9009 if (!RECURSIONOK(qctx->client)) {
9023 INSIST(!REDIRECT(qctx->client));
9029 result = ns_query_recurse(qctx->client, qctx->qtype, qname,
9035 result = ns_query_recurse(qctx->client, dns_rdatatype_a, qname,
9041 result = ns_query_recurse(qctx->client, qctx->qtype, qname,
9047 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
9049 qctx->client->query.attributes |= NS_QUERYATTR_DNS64;
9052 qctx->client->query.attributes |=
9076 ns_client_t *client = qctx->client;
9091 if (!WANTDNSSEC(client)) {
9098 rdataset = ns_client_newrdataset(client);
9099 sigrdataset = ns_client_newrdataset(client);
9105 dns_rdatatype_ds, 0, client->now, rdataset,
9113 0, client->now, rdataset, sigrdataset);
9128 result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
9140 dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
9146 result = dns_message_nextname(client->message,
9168 dbuf = ns_client_getnamebuf(client);
9169 fname = ns_client_newname(client, dbuf, &b);
9178 query_findclosestnsec3(name, qctx->db, qctx->version, client, rdataset,
9195 fixfname(client, &fname, &dbuf, &b);
9196 fixrdataset(client, &rdataset);
9197 fixrdataset(client, &sigrdataset);
9202 qctx->version, client, rdataset,
9213 ns_client_putrdataset(client, &rdataset);
9216 ns_client_putrdataset(client, &sigrdataset);
9219 ns_client_releasename(client, &fname);
9245 ns_client_putrdataset(qctx->client, &qctx->rdataset);
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);
9253 qctx->dbuf = ns_client_getnamebuf(qctx->client);
9254 qctx->fname = ns_client_newname(qctx->client,
9257 dns_name_copy(qctx->client->query.qname, qctx->fname);
9269 qctx->client->message->rdclass == dns_rdataclass_in &&
9284 qctx->client->query.dns64_ttl =
9290 qctx->client->query.dns64_ttl = 0;
9294 qctx->client->query.dns64_ttl =
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);
9318 ns_client_keepname(qctx->client, qctx->fname,
9320 dns_message_addname(qctx->client->message, qctx->fname,
9351 WANTDNSSEC(qctx->client))
9360 qname = qctx->client->query.qname;
9363 qctx->client, qctx->rdataset,
9373 (((qctx->client->manager->sctx->options &
9393 fixfname(qctx->client, &qctx->fname,
9395 fixrdataset(qctx->client, &qctx->rdataset);
9396 fixrdataset(qctx->client, &qctx->sigrdataset);
9416 qctx->client, qctx->rdataset,
9421 ns_client_releasename(qctx->client, &qctx->fname);
9431 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9438 ns_client_releasename(qctx->client, &qctx->fname);
9456 if (WANTDNSSEC(qctx->client) &&
9467 ns_client_t *client = qctx->client;
9508 dbuf = ns_client_getnamebuf(client);
9509 fname = ns_client_newname(client, dbuf, &b);
9532 INSIST(qctx->is_zone || REDIRECT(qctx->client));
9547 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
9554 ns_client_releasename(qctx->client, &qctx->fname);
9584 if (WANTDNSSEC(qctx->client)) {
9600 qctx->client->message->rcode = dns_rcode_noerror;
9602 qctx->client->message->rcode = dns_rcode_nxdomain;
9628 result = redirect(qctx->client, qctx->fname, qctx->rdataset,
9632 inc_stats(qctx->client, ns_statscounter_nxdomainredirect);
9646 result = redirect2(qctx->client, qctx->fname, qctx->rdataset,
9651 inc_stats(qctx->client, ns_statscounter_nxdomainredirect);
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;
9661 SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
9662 SAVE(qctx->client->query.redirect.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 =
9668 qctx->client->query.redirect.is_zone = qctx->is_zone;
9694 ns_client_logv(qctx->client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY,
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)) {
9774 if (WANTDNSSEC(qctx->client)) {
9782 inc_stats(qctx->client, ns_statscounter_nodatasynth);
9785 ns_client_releasename(qctx->client, &name);
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);
9835 if (WANTDNSSEC(qctx->client)) {
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);
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);
9905 if (!WANTRECURSION(qctx->client)) {
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)) {
9963 if (WANTDNSSEC(qctx->client)) {
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);
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);
10076 unsigned int dboptions = qctx->client->query.dboptions;
10091 dns_name_clone(qctx->client->query.qname, &qname);
10114 dns_clientinfo_init(&ci, qctx->client, NULL);
10136 result = dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname,
10155 qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client))
10160 soardataset = ns_client_newrdataset(qctx->client);
10161 sigsoardataset = ns_client_newrdataset(qctx->client);
10169 qctx->client->now, &node, fname, &cm,
10187 qctx->client->now, &node, nowild, &cm, &ci,
10217 RECURSIONOK(qctx->client))
10285 soardataset = ns_client_newrdataset(qctx->client);
10286 sigsoardataset = ns_client_newrdataset(qctx->client);
10292 dboptions, qctx->client->now, &node, fname, &cm,
10311 ns_client_putrdataset(qctx->client, &soardataset);
10314 ns_client_putrdataset(qctx->client, &sigsoardataset);
10333 ns_client_releasename(qctx->client, &qctx->fname);
10338 ns_client_putrdataset(qctx->client, &qctx->rdataset);
10340 ns_client_putrdataset(qctx->client, &qctx->sigrdataset);
10372 qctx->client->message->rcode = dns_rcode_nxdomain;
10376 qctx->client->message->rdclass == dns_rdataclass_in &&
10379 warn_rfc1918(qctx->client, qctx->fname, qctx->rdataset);
10399 qctx->rdataset->ttl != 0 || !RECURSIONOK(qctx->client))
10406 INSIST(!REDIRECT(qctx->client));
10408 result = ns_query_recurse(qctx->client, qctx->qtype,
10409 qctx->client->query.qname, NULL, NULL,
10413 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING;
10416 qctx->client->query.attributes |= NS_QUERYATTR_DNS64;
10419 qctx->client->query.attributes |=
10467 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
10471 if (WANTDNSSEC(qctx->client) && qctx->fname->attributes.wildcard) {
10478 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) {
10484 if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
10485 query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
10497 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
10503 dns_message_gettempname(qctx->client->message, &tname);
10507 dns_message_puttempname(qctx->client->message, &tname);
10520 ns_client_qnamereplace(qctx->client, tname);
10522 if (!WANTRECURSION(qctx->client)) {
10560 namereln = dns_name_fullcompare(qctx->client->query.qname, qctx->fname,
10574 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
10578 if (WANTDNSSEC(qctx->client) && qctx->fname->attributes.wildcard) {
10585 if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
10586 query_prefetch(qctx->client, qctx->fname, qctx->rdataset);
10595 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER;
10601 dns_message_gettempname(qctx->client->message, &tname);
10605 dns_message_puttempname(qctx->client->message, &tname);
10623 dns_name_split(qctx->client->query.qname, nlabels, prefix, NULL);
10625 qctx->dbuf = ns_client_getnamebuf(qctx->client);
10626 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
10628 dns_message_puttempname(qctx->client->message, &tname);
10636 qctx->client->message->rcode = dns_rcode_yxdomain;
10643 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf);
10671 ns_client_qnamereplace(qctx->client, qctx->fname);
10674 if (!WANTRECURSION(qctx->client)) {
10692 ns_client_t *client = qctx->client;
10699 dns_message_gettempname(client->message, &aname);
10701 dns_name_copy(client->query.qname, aname);
10703 dns_message_gettemprdatalist(client->message, &rdatalist);
10705 dns_message_gettemprdata(client->message, &rdata);
10707 dns_message_gettemprdataset(client->message, &rdataset);
10710 rdatalist->rdclass = client->message->rdclass;
10716 rdata->rdclass = client->message->rdclass;
10729 dns_message_puttemprdataset(client->message, &rdataset);
10732 dns_message_puttempname(client->message, &aname);
10749 if (WANTDNSSEC(qctx->client) && qctx->fname->attributes.wildcard) {
10779 ns_client_t *client = qctx->client;
10791 dns_clientinfo_init(&ci, client, NULL);
10796 if (((client->manager->sctx->options & NS_SERVER_NOSOA) != 0) &&
10797 (!WANTDNSSEC(client) || !dns_rdataset_isassociated(qctx->rdataset)))
10805 dns_message_gettempname(client->message, &name);
10813 rdataset = ns_client_newrdataset(client);
10814 if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
10815 sigrdataset = ns_client_newrdataset(client);
10824 dns_rdatatype_soa, 0, client->now,
10834 client->query.dboptions, 0, &node,
10888 ns_client_putrdataset(client, &rdataset);
10890 ns_client_putrdataset(client, &sigrdataset);
10893 ns_client_releasename(client, &name);
10907 ns_client_t *client = qctx->client;
10926 dns_clientinfo_init(&ci, client, NULL);
10931 dns_message_gettempname(client->message, &name);
10933 rdataset = ns_client_newrdataset(client);
10935 if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) {
10936 sigrdataset = ns_client_newrdataset(client);
10945 dns_rdatatype_ns, 0, client->now,
10950 client->query.dboptions, 0, &node,
10972 ns_client_putrdataset(client, &rdataset);
10974 ns_client_putrdataset(client, &sigrdataset);
10977 ns_client_releasename(client, &name);
10992 ns_client_t *client = qctx->client;
11011 dns_clientinfo_init(&ci, client, NULL);
11014 dns_name_clone(client->query.qname, &qname);
11020 result = query_getdb(client, &qname, dns_rdatatype_ns,
11042 if (!USECACHE(client)) {
11045 dns_db_attach(client->view->cachedb, &db);
11055 dbuf = ns_client_getnamebuf(client);
11056 fname = ns_client_newname(client, dbuf, &b);
11057 rdataset = ns_client_newrdataset(client);
11060 * Get the RRSIGs if the client requested them or if we may
11063 if (WANTDNSSEC(client) || !is_zone) {
11064 sigrdataset = ns_client_newrdataset(client);
11072 db, client->query.qname, version, dns_rdatatype_ns,
11073 client->query.dboptions, client->now, &node, fname, &cm,
11078 if (USECACHE(client)) {
11079 ns_client_keepname(client, fname, dbuf);
11086 dns_db_attach(client->view->cachedb, &db);
11092 db, client->query.qname, client->query.dboptions,
11093 client->now, &node, fname, NULL, rdataset, sigrdataset);
11116 ns_client_releasename(client, &fname);
11124 ns_client_putrdataset(client, &rdataset);
11126 ns_client_putrdataset(client, &sigrdataset);
11145 !validate(client, db, fname, rdataset, sigrdataset) &&
11146 !PENDINGOK(client->query.dboptions))
11153 !validate(client, db, fname, rdataset, sigrdataset) &&
11154 SECURE(client) && WANTDNSSEC(client))
11161 * when the client may be looking for AD in the response.
11163 if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) &&
11171 * If the client doesn't want DNSSEC we can discard the sigrdataset
11174 if (!WANTDNSSEC(client)) {
11175 ns_client_putrdataset(client, &sigrdataset);
11183 ns_client_putrdataset(client, &rdataset);
11186 ns_client_putrdataset(client, &sigrdataset);
11189 ns_client_releasename(client, &fname);
11201 ns_client_putrdataset(client, &zrdataset);
11203 ns_client_putrdataset(client, &zsigrdataset);
11206 ns_client_releasename(client, &zfname);
11214 ns_client_t *client = qctx->client;
11237 dns_clientinfo_init(&ci, client, NULL);
11242 * qctx->wildcardname. Otherwise we just use the client
11248 name = client->query.qname;
11293 options = client->query.dboptions | DNS_DBFIND_NOWILD;
11300 dbuf = ns_client_getnamebuf(client);
11301 fname = ns_client_newname(client, dbuf, &b);
11302 rdataset = ns_client_newrdataset(client);
11303 sigrdataset = ns_client_newrdataset(client);
11347 query_findclosestnsec3(cname, qctx->db, qctx->version, client,
11362 dbuf = ns_client_getnamebuf(client);
11363 fname = ns_client_newname(client, dbuf, &b);
11367 rdataset = ns_client_newrdataset(client);
11373 sigrdataset = ns_client_newrdataset(client);
11388 query_findclosestnsec3(wname, qctx->db, qctx->version, client,
11405 dbuf = ns_client_getnamebuf(client);
11406 fname = ns_client_newname(client, dbuf, &b);
11410 rdataset = ns_client_newrdataset(client);
11416 sigrdataset = ns_client_newrdataset(client);
11430 query_findclosestnsec3(wname, qctx->db, qctx->version, client,
11476 ns_client_putrdataset(client, &rdataset);
11479 ns_client_putrdataset(client, &sigrdataset);
11482 ns_client_releasename(client, &fname);
11493 ns_client_putrdataset(client, &rdataset);
11496 ns_client_putrdataset(client, &sigrdataset);
11499 ns_client_releasename(client, &fname);
11514 if (!qctx->want_restart && !NOAUTHORITY(qctx->client)) {
11523 ns_client_releasename(qctx->client,
11569 * Find the sortlist statement that applies to 'client' and set up
11570 * the sortlist info in in client->message appropriately.
11575 ns_client_t *client = qctx->client;
11576 dns_aclenv_t *env = client->manager->aclenv;
11581 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
11582 switch (ns_sortlist_setup(client->view->sortlist, env, &netaddr,
11587 dns_message_setsortorder(client->message,
11593 dns_message_setsortorder(client->message,
11611 const dns_namelist_t *secs = qctx->client->message->sections;
11618 qctx->client->message->rcode != dns_rcode_noerror ||
11625 msg = qctx->client->message;
11629 if (dns_name_equal(name, qctx->client->query.qname)) {
11653 const dns_namelist_t *secs = qctx->client->message->sections;
11663 qctx->rpz_st = qctx->client->query.rpz_st;
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;
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,
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;
11717 ns_client_extendederror(qctx->client, 0,
11719 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
11726 (!PARTIALANSWER(qctx->client) ||
11727 (WANTRECURSION(qctx->client) && !partial_result_with_servfail) ||
11739 query_next(qctx->client, qctx->result);
11742 * If we don't have any answer to give the client,
11743 * or if the client requested recursion and thus wanted
11747 query_error(qctx->client, qctx->result, qctx->line);
11758 if (RECURSING(qctx->client) &&
11759 (!QUERY_STALETIMEOUT(&qctx->client->query) ||
11775 if (qctx->client->message->rcode == dns_rcode_nxdomain &&
11778 qctx->client->message->flags |= DNS_MESSAGEFLAG_AA;
11782 * If the response is somehow unexpected for the client and this
11788 qctx->client->message->rcode != dns_rcode_noerror))
11795 query_send(qctx->client);
11802 * is available, i.e. "stale-anwer-client-timeout 0". But, we
11807 message_clearrdataset(qctx->client->message, 0);
11808 query_stale_refresh(qctx->client);
11820 log_tat(ns_client_t *client) {
11832 if ((client->query.qtype != dns_rdatatype_null ||
11833 !dns_name_istat(client->query.qname)) &&
11834 (client->keytag == NULL ||
11835 client->query.qtype != dns_rdatatype_dnskey))
11840 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
11841 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
11843 dns_rdataclass_format(client->view->rdclass, classbuf,
11846 if (client->query.qtype == dns_rdatatype_dnskey) {
11847 uint16_t keytags = client->keytag_len / 2;
11849 char *cp = tags = isc_mem_get(client->manager->mctx, taglen);
11852 INSIST(client->keytag != NULL);
11857 keytag = (client->keytag[i * 2] << 8) |
11858 client->keytag[i * 2 + 1];
11875 isc_mem_put(client->manager->mctx, tags, taglen);
11880 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
11894 rdataset = ISC_LIST_HEAD(client->query.qname->list);
11896 dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
11899 isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf));
11901 if (HAVEECS(client)) {
11902 ns_client_log_ecs(client, ecsbuf, sizeof(ecsbuf));
11904 ns_client_log_flags(client, flags, extflags, flagsbuf,
11907 ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, level,
11913 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
11931 if (client->query.origqname != NULL) {
11932 dns_name_format(client->query.origqname, namebuf,
11937 rdataset = ISC_LIST_HEAD(client->query.origqname->list);
11949 ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY,
11956 ns_query_start(ns_client_t *client, isc_nmhandle_t *handle) {
11964 REQUIRE(NS_CLIENT_VALID(client));
11969 isc_nmhandle_attach(handle, &client->reqhandle);
11971 message = client->message;
11972 saved_extflags = client->extflags;
11973 saved_flags = client->message->flags;
11980 client->cleanup = query_cleanup;
11983 client->query.attributes |= NS_QUERYATTR_WANTRECURSION;
11986 if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) {
11987 client->attributes |= NS_CLIENTATTR_WANTDNSSEC;
11990 switch (client->view->minimalresponses) {
11994 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
11998 client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
12002 client->query.attributes |= NS_QUERYATTR_NOAUTHORITY;
12007 if (client->view->cachedb == NULL || !client->view->recursion) {
12012 client->query.attributes &= ~(NS_QUERYATTR_RECURSIONOK |
12014 client->attributes |= NS_CLIENTATTR_NOSETFC;
12015 } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 ||
12019 * If the client isn't allowed to recurse (due to
12024 client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
12025 client->attributes |= NS_CLIENTATTR_NOSETFC;
12032 query_error(client, DNS_R_FORMERR, __LINE__);
12041 query_error(client, result, __LINE__);
12045 &client->query.qname);
12046 client->query.origqname = client->query.qname;
12054 query_error(client, DNS_R_FORMERR, __LINE__);
12056 query_error(client, result, __LINE__);
12061 if ((client->manager->sctx->options & NS_SERVER_LOGQUERIES) != 0) {
12062 log_query(client, saved_flags, saved_extflags);
12068 rdataset = ISC_LIST_HEAD(client->query.qname->list);
12070 client->query.qtype = qtype = rdataset->type;
12071 dns_rdatatypestats_increment(client->manager->sctx->rcvquerystats,
12074 log_tat(client);
12098 query_error(client, DNS_R_NOTIMP, __LINE__);
12114 query_error(client, DNS_R_NOALPN,
12118 query_error(client, DNS_R_REFUSED,
12123 ns_xfr_start(client, rdataset->type);
12127 query_error(client, DNS_R_NOTIMP, __LINE__);
12131 client->message, client->manager->sctx->tkeyctx,
12132 client->view->dynamickeys);
12134 query_send(client);
12136 query_error(client, result, __LINE__);
12140 query_error(client, DNS_R_FORMERR, __LINE__);
12149 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
12155 client->query.attributes &= ~(NS_QUERYATTR_NOAUTHORITY |
12162 if (qtype == dns_rdatatype_any && client->view->minimal_any &&
12163 !TCP(client))
12165 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
12172 if (client->ednsversion >= 0 && client->udpsize <= 512U && !TCP(client))
12174 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
12179 * If the client has requested that DNSSEC checking be disabled,
12189 client->query.dboptions |= DNS_DBFIND_PENDINGOK;
12190 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
12191 } else if (!client->view->enablevalidation) {
12192 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE;
12195 if (client->view->qminimization) {
12196 client->query.fetchoptions |= DNS_FETCHOPT_QMINIMIZE |
12198 if (client->view->qmin_strict) {
12199 client->query.fetchoptions |= DNS_FETCHOPT_QMIN_STRICT;
12208 client->query.attributes &= ~NS_QUERYATTR_SECURE;
12212 * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query.
12216 client->attributes |= NS_CLIENTATTR_WANTAD;
12224 query_next(client, result);
12235 if ((client->manager->sctx->options & NS_SERVER_NOAA) == 0) {
12243 if (WANTDNSSEC(client) || WANTAD(client)) {
12247 query_setup(client, qtype);