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