1/* $NetBSD: query.h,v 1.8 2024/02/21 22:52:46 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16#pragma once 17 18/*! \file */ 19 20#include <stdbool.h> 21 22#include <isc/buffer.h> 23#include <isc/netaddr.h> 24#include <isc/task.h> 25#include <isc/types.h> 26 27#include <dns/rdataset.h> 28#include <dns/resolver.h> 29#include <dns/rpz.h> 30#include <dns/types.h> 31 32#include <ns/types.h> 33 34/*% nameserver database version structure */ 35typedef struct ns_dbversion { 36 dns_db_t *db; 37 dns_dbversion_t *version; 38 bool acl_checked; 39 bool queryok; 40 ISC_LINK(struct ns_dbversion) link; 41} ns_dbversion_t; 42 43/*% 44 * nameserver recursion parameters, to uniquely identify a recursion 45 * query; this is used to detect a recursion loop 46 */ 47typedef struct ns_query_recparam { 48 dns_rdatatype_t qtype; 49 dns_name_t *qname; 50 dns_fixedname_t fqname; 51 dns_name_t *qdomain; 52 dns_fixedname_t fqdomain; 53} ns_query_recparam_t; 54 55/*% nameserver query structure */ 56struct ns_query { 57 unsigned int attributes; 58 unsigned int restarts; 59 bool timerset; 60 dns_name_t *qname; 61 dns_name_t *origqname; 62 dns_rdatatype_t qtype; 63 unsigned int dboptions; 64 unsigned int fetchoptions; 65 dns_db_t *gluedb; 66 dns_db_t *authdb; 67 dns_zone_t *authzone; 68 bool authdbset; 69 bool isreferral; 70 isc_mutex_t fetchlock; 71 dns_fetch_t *fetch; 72 dns_fetch_t *prefetch; 73 ns_hookasync_t *hookactx; 74 dns_rpz_st_t *rpz_st; 75 isc_bufferlist_t namebufs; 76 ISC_LIST(ns_dbversion_t) activeversions; 77 ISC_LIST(ns_dbversion_t) freeversions; 78 dns_rdataset_t *dns64_aaaa; 79 dns_rdataset_t *dns64_sigaaaa; 80 bool *dns64_aaaaok; 81 unsigned int dns64_aaaaoklen; 82 unsigned int dns64_options; 83 unsigned int dns64_ttl; 84 85 struct { 86 dns_db_t *db; 87 dns_zone_t *zone; 88 dns_dbnode_t *node; 89 dns_rdatatype_t qtype; 90 dns_name_t *fname; 91 dns_fixedname_t fixed; 92 isc_result_t result; 93 dns_rdataset_t *rdataset; 94 dns_rdataset_t *sigrdataset; 95 bool authoritative; 96 bool is_zone; 97 } redirect; 98 99 ns_query_recparam_t recparam; 100 101 dns_keytag_t root_key_sentinel_keyid; 102 bool root_key_sentinel_is_ta; 103 bool root_key_sentinel_not_ta; 104}; 105 106#define NS_QUERYATTR_RECURSIONOK 0x000001 107#define NS_QUERYATTR_CACHEOK 0x000002 108#define NS_QUERYATTR_PARTIALANSWER 0x000004 109#define NS_QUERYATTR_NAMEBUFUSED 0x000008 110#define NS_QUERYATTR_RECURSING 0x000010 111#define NS_QUERYATTR_QUERYOKVALID 0x000040 112#define NS_QUERYATTR_QUERYOK 0x000080 113#define NS_QUERYATTR_WANTRECURSION 0x000100 114#define NS_QUERYATTR_SECURE 0x000200 115#define NS_QUERYATTR_NOAUTHORITY 0x000400 116#define NS_QUERYATTR_NOADDITIONAL 0x000800 117#define NS_QUERYATTR_CACHEACLOKVALID 0x001000 118#define NS_QUERYATTR_CACHEACLOK 0x002000 119#define NS_QUERYATTR_DNS64 0x004000 120#define NS_QUERYATTR_DNS64EXCLUDE 0x008000 121#define NS_QUERYATTR_RRL_CHECKED 0x010000 122#define NS_QUERYATTR_REDIRECT 0x020000 123#define NS_QUERYATTR_ANSWERED 0x040000 124#define NS_QUERYATTR_STALEOK 0x080000 125#define NS_QUERYATTR_STALEPENDING 0x100000 126 127typedef struct query_ctx query_ctx_t; 128 129/* query context structure */ 130struct query_ctx { 131 isc_buffer_t *dbuf; /* name buffer */ 132 dns_name_t *fname; /* found name from DB lookup */ 133 dns_name_t *tname; /* temporary name, used 134 * when processing ANY 135 * queries */ 136 dns_rdataset_t *rdataset; /* found rdataset */ 137 dns_rdataset_t *sigrdataset; /* found sigrdataset */ 138 dns_rdataset_t *noqname; /* rdataset needing 139 * NOQNAME proof */ 140 dns_rdatatype_t qtype; 141 dns_rdatatype_t type; 142 143 unsigned int options; /* DB lookup options */ 144 145 bool redirected; /* nxdomain redirected? */ 146 bool is_zone; /* is DB a zone DB? */ 147 bool is_staticstub_zone; 148 bool resuming; /* resumed from recursion? */ 149 bool dns64, dns64_exclude, rpz; 150 bool authoritative; /* authoritative query? */ 151 bool want_restart; /* CNAME chain or other 152 * restart needed */ 153 bool refresh_rrset; /* stale RRset refresh needed */ 154 bool need_wildcardproof; /* wildcard proof needed */ 155 bool nxrewrite; /* negative answer from RPZ */ 156 bool findcoveringnsec; /* lookup covering NSEC */ 157 bool answer_has_ns; /* NS is in answer */ 158 dns_fixedname_t wildcardname; /* name needing wcard proof */ 159 dns_fixedname_t dsname; /* name needing DS */ 160 161 ns_client_t *client; /* client object */ 162 bool detach_client; /* client needs detaching */ 163 164 dns_fetchevent_t *event; /* recursion event */ 165 166 dns_db_t *db; /* zone or cache database */ 167 dns_dbversion_t *version; /* DB version */ 168 dns_dbnode_t *node; /* DB node */ 169 170 dns_db_t *zdb; /* zone DB values, saved */ 171 dns_dbnode_t *znode; /* while searching cache */ 172 dns_name_t *zfname; /* for a better answer */ 173 dns_dbversion_t *zversion; 174 dns_rdataset_t *zrdataset; 175 dns_rdataset_t *zsigrdataset; 176 177 dns_rpz_st_t *rpz_st; /* RPZ state */ 178 dns_zone_t *zone; /* zone to search */ 179 180 dns_view_t *view; /* client view */ 181 182 isc_result_t result; /* query result */ 183 int line; /* line to report error */ 184}; 185 186typedef isc_result_t (*ns_query_starthookasync_t)( 187 query_ctx_t *qctx, isc_mem_t *mctx, void *arg, isc_task_t *task, 188 isc_taskaction_t action, void *evarg, ns_hookasync_t **ctxp); 189 190/* 191 * The following functions are expected to be used only within query.c 192 * and query modules. 193 */ 194 195isc_result_t 196ns_query_done(query_ctx_t *qctx); 197/*%< 198 * Finalize this phase of the query process: 199 * 200 * - Clean up. 201 * - If we have an answer ready (positive or negative), send it. 202 * - If we need to restart for a chaining query, call ns__query_start() again. 203 * - If we've started recursion, then just clean up; things will be 204 * restarted via fetch_callback()/query_resume(). 205 */ 206 207isc_result_t 208ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, 209 dns_name_t *qdomain, dns_rdataset_t *nameservers, 210 bool resuming); 211/*%< 212 * Prepare client for recursion, then create a resolver fetch, with 213 * the event callback set to fetch_callback(). Afterward we terminate 214 * this phase of the query, and resume with a new query context when 215 * recursion completes. 216 */ 217 218isc_result_t 219ns_query_hookasync(query_ctx_t *qctx, ns_query_starthookasync_t runasync, 220 void *arg); 221/*%< 222 * Prepare the client for an asynchronous hook action, then call the 223 * specified 'runasync' function to start an asynchronous process running 224 * in the background. This function works similarly to ns_query_recurse(), 225 * but is expected to be called from a query hook action to support 226 * asynchronous event handling in a hook. A typical use case would be for 227 * a plugin to initiate recursion, but it may also be used to carry out 228 * other time-consuming tasks without blocking the caller or the worker 229 * thread. 230 * 231 * The calling plugin action must pass 'qctx' as passed from the query 232 * module. 233 * 234 * Once a plugin action calls this function, the ownership of 'qctx' is 235 * essentially transferred to the query module. Regardless of the return 236 * value of this function, the hook must not use 'qctx' anymore. 237 * 238 * This function must not be called after ns_query_recurse() is called, 239 * until the fetch is completed, as it needs resources that 240 * ns_query_recurse() would also use. 241 * 242 * See hooks.h for details about how 'runasync' is supposed to work, and 243 * other aspects of hook-triggered asynchronous event handling. 244 */ 245 246isc_result_t 247ns_query_init(ns_client_t *client); 248 249void 250ns_query_free(ns_client_t *client); 251 252void 253ns_query_start(ns_client_t *client, isc_nmhandle_t *handle); 254 255void 256ns_query_cancel(ns_client_t *client); 257 258/* 259 * The following functions are expected to be used only within query.c 260 * and query modules. 261 */ 262 263isc_result_t 264ns__query_sfcache(query_ctx_t *qctx); 265/*%< 266 * (Must not be used outside this module and its associated unit tests.) 267 */ 268 269isc_result_t 270ns__query_start(query_ctx_t *qctx); 271/*%< 272 * (Must not be used outside this module and its associated unit tests.) 273 */ 274