1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * util/module.h - DNS handling module interface 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 39b7579f77SDag-Erling Smørgrav * This file contains the interface for DNS handling modules. 4017d15b25SDag-Erling Smørgrav * 4117d15b25SDag-Erling Smørgrav * The module interface uses the DNS modules as state machines. The 4217d15b25SDag-Erling Smørgrav * state machines are activated in sequence to operate on queries. Once 4317d15b25SDag-Erling Smørgrav * they are done, the reply is passed back. In the usual setup the mesh 4417d15b25SDag-Erling Smørgrav * is the caller of the state machines and once things are done sends replies 4517d15b25SDag-Erling Smørgrav * and invokes result callbacks. 4617d15b25SDag-Erling Smørgrav * 4717d15b25SDag-Erling Smørgrav * The module provides a number of functions, listed in the module_func_block. 4817d15b25SDag-Erling Smørgrav * The module is inited and destroyed and memory usage queries, for the 4917d15b25SDag-Erling Smørgrav * module as a whole, for entire-module state (such as a cache). And per-query 5017d15b25SDag-Erling Smørgrav * functions are called, operate to move the state machine and cleanup of 5117d15b25SDag-Erling Smørgrav * the per-query state. 5217d15b25SDag-Erling Smørgrav * 5317d15b25SDag-Erling Smørgrav * Most per-query state should simply be allocated in the query region. 5417d15b25SDag-Erling Smørgrav * This is destroyed at the end of the query. 5517d15b25SDag-Erling Smørgrav * 5617d15b25SDag-Erling Smørgrav * The module environment contains services and information and caches 5717d15b25SDag-Erling Smørgrav * shared by the modules and the rest of the system. It also contains 5817d15b25SDag-Erling Smørgrav * function pointers for module-specific tasks (like sending queries). 5917d15b25SDag-Erling Smørgrav * 6017d15b25SDag-Erling Smørgrav * *** Example module calls for a normal query 6117d15b25SDag-Erling Smørgrav * 6217d15b25SDag-Erling Smørgrav * In this example, the query does not need recursion, all the other data 6317d15b25SDag-Erling Smørgrav * can be found in the cache. This makes the example shorter. 6417d15b25SDag-Erling Smørgrav * 6517d15b25SDag-Erling Smørgrav * At the start of the program the iterator module is initialised. 6617d15b25SDag-Erling Smørgrav * The iterator module sets up its global state, such as donotquery lists 6717d15b25SDag-Erling Smørgrav * and private address trees. 6817d15b25SDag-Erling Smørgrav * 6917d15b25SDag-Erling Smørgrav * A query comes in, and a mesh entry is created for it. The mesh 7017d15b25SDag-Erling Smørgrav * starts the resolution process. The validator module is the first 7117d15b25SDag-Erling Smørgrav * in the list of modules, and it is started on this new query. The 7217d15b25SDag-Erling Smørgrav * operate() function is called. The validator decides it needs not do 7317d15b25SDag-Erling Smørgrav * anything yet until there is a result and returns wait_module, that 7417d15b25SDag-Erling Smørgrav * causes the next module in the list to be started. 7517d15b25SDag-Erling Smørgrav * 7617d15b25SDag-Erling Smørgrav * The next module is the iterator. It is started on the passed query and 7717d15b25SDag-Erling Smørgrav * decides to perform a lookup. For this simple example, the delegation 7817d15b25SDag-Erling Smørgrav * point information is available, and all the iterator wants to do is 7917d15b25SDag-Erling Smørgrav * send a UDP query. The iterator uses env.send_query() to send the 8017d15b25SDag-Erling Smørgrav * query. Then the iterator suspends (returns from the operate call). 8117d15b25SDag-Erling Smørgrav * 8217d15b25SDag-Erling Smørgrav * When the UDP reply comes back (and on errors and timeouts), the 8317d15b25SDag-Erling Smørgrav * operate function is called for the query, on the iterator module, 8417d15b25SDag-Erling Smørgrav * with the event that there is a reply. The iterator decides that this 8517d15b25SDag-Erling Smørgrav * is enough, the work is done. It returns the value finished from the 8617d15b25SDag-Erling Smørgrav * operate call, which causes the previous module to be started. 8717d15b25SDag-Erling Smørgrav * 8817d15b25SDag-Erling Smørgrav * The previous module, the validator module, is started with the event 8917d15b25SDag-Erling Smørgrav * that the iterator module is done. The validator decides to validate 9017d15b25SDag-Erling Smørgrav * the query. Once it is done (which could take recursive lookups, but 9117d15b25SDag-Erling Smørgrav * in this example no recursive lookups are needed), it returns from the 9217d15b25SDag-Erling Smørgrav * operate function with finished. 9317d15b25SDag-Erling Smørgrav * 9417d15b25SDag-Erling Smørgrav * There is no previous module from the validator module, and the mesh 9517d15b25SDag-Erling Smørgrav * takes this to mean that the query is finally done. The mesh invokes 9617d15b25SDag-Erling Smørgrav * callbacks and sends packets to queriers. 9717d15b25SDag-Erling Smørgrav * 9817d15b25SDag-Erling Smørgrav * If other modules had been waiting (recursively) on the answer to this 9917d15b25SDag-Erling Smørgrav * query, then the mesh will tell them about it. It calls the inform_super 10017d15b25SDag-Erling Smørgrav * routine on all the waiting modules, and once that is done it calls all of 10117d15b25SDag-Erling Smørgrav * them with the operate() call. During inform_super the query that is done 10217d15b25SDag-Erling Smørgrav * still exists and information can be copied from it (but the module should 10317d15b25SDag-Erling Smørgrav * not really re-entry codepoints and services). During the operate call 10417d15b25SDag-Erling Smørgrav * the modules can use stored state to continue operation with the results. 10517d15b25SDag-Erling Smørgrav * (network buffers are used to contain the answer packet during the 10617d15b25SDag-Erling Smørgrav * inform_super phase, but after that the network buffers will be cleared 10717d15b25SDag-Erling Smørgrav * of their contents so that other tasks can be performed). 10817d15b25SDag-Erling Smørgrav * 10917d15b25SDag-Erling Smørgrav * *** Example module calls for recursion 11017d15b25SDag-Erling Smørgrav * 11117d15b25SDag-Erling Smørgrav * A module is called in operate, and it decides that it wants to perform 11217d15b25SDag-Erling Smørgrav * recursion. That is, it wants the full state-machine-list to operate on 11317d15b25SDag-Erling Smørgrav * a different query. It calls env.attach_sub() to create a new query state. 11417d15b25SDag-Erling Smørgrav * The routine returns the newly created state, and potentially the module 11517d15b25SDag-Erling Smørgrav * can edit the module-states for the newly created query (i.e. pass along 11617d15b25SDag-Erling Smørgrav * some information, like delegation points). The module then suspends, 11717d15b25SDag-Erling Smørgrav * returns from the operate routine. 11817d15b25SDag-Erling Smørgrav * 11917d15b25SDag-Erling Smørgrav * The mesh meanwhile will have the newly created query (or queries) on 12017d15b25SDag-Erling Smørgrav * a waiting list, and will call operate() on this query (or queries). 12117d15b25SDag-Erling Smørgrav * It starts again at the start of the module list for them. The query 12217d15b25SDag-Erling Smørgrav * (or queries) continue to operate their state machines, until they are 12317d15b25SDag-Erling Smørgrav * done. When they are done the mesh calls inform_super on the module that 12417d15b25SDag-Erling Smørgrav * wanted the recursion. After that the mesh calls operate() on the module 12517d15b25SDag-Erling Smørgrav * that wanted to do the recursion, and during this phase the module could, 12617d15b25SDag-Erling Smørgrav * for example, decide to create more recursions. 12717d15b25SDag-Erling Smørgrav * 12817d15b25SDag-Erling Smørgrav * If the module decides it no longer wants the recursive information 12917d15b25SDag-Erling Smørgrav * it can call detach_subs. Those queries will still run to completion, 13017d15b25SDag-Erling Smørgrav * potentially filling the cache with information. Inform_super is not 13117d15b25SDag-Erling Smørgrav * called any more. 13217d15b25SDag-Erling Smørgrav * 13317d15b25SDag-Erling Smørgrav * The iterator module will fetch items from the cache, so a recursion 13417d15b25SDag-Erling Smørgrav * attempt may complete very quickly if the item is in cache. The calling 13517d15b25SDag-Erling Smørgrav * module has to wait for completion or eventual timeout. A recursive query 13617d15b25SDag-Erling Smørgrav * that times out returns a servfail rcode (servfail is also returned for 13717d15b25SDag-Erling Smørgrav * other errors during the lookup). 13817d15b25SDag-Erling Smørgrav * 13917d15b25SDag-Erling Smørgrav * Results are passed in the qstate, the rcode member is used to pass 14017d15b25SDag-Erling Smørgrav * errors without requiring memory allocation, so that the code can continue 14117d15b25SDag-Erling Smørgrav * in out-of-memory conditions. If the rcode member is 0 (NOERROR) then 14217d15b25SDag-Erling Smørgrav * the dns_msg entry contains a filled out message. This message may 14317d15b25SDag-Erling Smørgrav * also contain an rcode that is nonzero, but in this case additional 14417d15b25SDag-Erling Smørgrav * information (query, additional) can be passed along. 14517d15b25SDag-Erling Smørgrav * 14656850988SCy Schubert * The rcode and dns_msg are used to pass the result from the rightmost 14717d15b25SDag-Erling Smørgrav * module towards the leftmost modules and then towards the user. 14817d15b25SDag-Erling Smørgrav * 14917d15b25SDag-Erling Smørgrav * If you want to avoid recursion-cycles where queries need other queries 15017d15b25SDag-Erling Smørgrav * that need the first one, use detect_cycle() to see if that will happen. 15117d15b25SDag-Erling Smørgrav * 152b7579f77SDag-Erling Smørgrav */ 153b7579f77SDag-Erling Smørgrav 154b7579f77SDag-Erling Smørgrav #ifndef UTIL_MODULE_H 155b7579f77SDag-Erling Smørgrav #define UTIL_MODULE_H 156b7579f77SDag-Erling Smørgrav #include "util/storage/lruhash.h" 157b7579f77SDag-Erling Smørgrav #include "util/data/msgreply.h" 158b7579f77SDag-Erling Smørgrav #include "util/data/msgparse.h" 15917d15b25SDag-Erling Smørgrav struct sldns_buffer; 160b7579f77SDag-Erling Smørgrav struct alloc_cache; 161b7579f77SDag-Erling Smørgrav struct rrset_cache; 162b7579f77SDag-Erling Smørgrav struct key_cache; 163b7579f77SDag-Erling Smørgrav struct config_file; 164b7579f77SDag-Erling Smørgrav struct slabhash; 165b7579f77SDag-Erling Smørgrav struct query_info; 166b7579f77SDag-Erling Smørgrav struct edns_data; 167b7579f77SDag-Erling Smørgrav struct regional; 168b7579f77SDag-Erling Smørgrav struct worker; 16957bddd21SDag-Erling Smørgrav struct comm_base; 17057bddd21SDag-Erling Smørgrav struct auth_zones; 17157bddd21SDag-Erling Smørgrav struct outside_network; 172b7579f77SDag-Erling Smørgrav struct module_qstate; 173b7579f77SDag-Erling Smørgrav struct ub_randstate; 174b7579f77SDag-Erling Smørgrav struct mesh_area; 175b7579f77SDag-Erling Smørgrav struct mesh_state; 176b7579f77SDag-Erling Smørgrav struct val_anchors; 177b7579f77SDag-Erling Smørgrav struct val_neg_cache; 178b7579f77SDag-Erling Smørgrav struct iter_forwards; 179b7579f77SDag-Erling Smørgrav struct iter_hints; 18065b390aaSDag-Erling Smørgrav struct respip_set; 18165b390aaSDag-Erling Smørgrav struct respip_client_info; 18265b390aaSDag-Erling Smørgrav struct respip_addr_info; 183335c7cdaSCy Schubert struct module_stack; 184b7579f77SDag-Erling Smørgrav 185b7579f77SDag-Erling Smørgrav /** Maximum number of modules in operation */ 1863005e0a3SDag-Erling Smørgrav #define MAX_MODULE 16 187b7579f77SDag-Erling Smørgrav 188bc892140SDag-Erling Smørgrav /** Maximum number of known edns options */ 189bc892140SDag-Erling Smørgrav #define MAX_KNOWN_EDNS_OPTS 256 190bc892140SDag-Erling Smørgrav 191a39a5a69SCy Schubert struct errinf_strlist { 192a39a5a69SCy Schubert /** next item in list */ 193a39a5a69SCy Schubert struct errinf_strlist* next; 194a39a5a69SCy Schubert /** config option string */ 195a39a5a69SCy Schubert char* str; 196a39a5a69SCy Schubert /** EDE code companion to the error str */ 197a39a5a69SCy Schubert int reason_bogus; 198a39a5a69SCy Schubert }; 199a39a5a69SCy Schubert 200bc892140SDag-Erling Smørgrav enum inplace_cb_list_type { 201bc892140SDag-Erling Smørgrav /* Inplace callbacks for when a resolved reply is ready to be sent to the 202bc892140SDag-Erling Smørgrav * front.*/ 203bc892140SDag-Erling Smørgrav inplace_cb_reply = 0, 204bc892140SDag-Erling Smørgrav /* Inplace callbacks for when a reply is given from the cache. */ 205bc892140SDag-Erling Smørgrav inplace_cb_reply_cache, 206bc892140SDag-Erling Smørgrav /* Inplace callbacks for when a reply is given with local data 207bc892140SDag-Erling Smørgrav * (or Chaos reply). */ 208bc892140SDag-Erling Smørgrav inplace_cb_reply_local, 209bc892140SDag-Erling Smørgrav /* Inplace callbacks for when the reply is servfail. */ 210bc892140SDag-Erling Smørgrav inplace_cb_reply_servfail, 211bc892140SDag-Erling Smørgrav /* Inplace callbacks for when a query is ready to be sent to the back.*/ 212bc892140SDag-Erling Smørgrav inplace_cb_query, 21365b390aaSDag-Erling Smørgrav /* Inplace callback for when a reply is received from the back. */ 21465b390aaSDag-Erling Smørgrav inplace_cb_query_response, 21565b390aaSDag-Erling Smørgrav /* Inplace callback for when EDNS is parsed on a reply received from the 21665b390aaSDag-Erling Smørgrav * back. */ 21765b390aaSDag-Erling Smørgrav inplace_cb_edns_back_parsed, 218bc892140SDag-Erling Smørgrav /* Total number of types. Used for array initialization. 219bc892140SDag-Erling Smørgrav * Should always be last. */ 220bc892140SDag-Erling Smørgrav inplace_cb_types_total 221bc892140SDag-Erling Smørgrav }; 222bc892140SDag-Erling Smørgrav 223bc892140SDag-Erling Smørgrav 224bc892140SDag-Erling Smørgrav /** Known edns option. Can be populated during modules' init. */ 225bc892140SDag-Erling Smørgrav struct edns_known_option { 226bc892140SDag-Erling Smørgrav /** type of this edns option */ 227bc892140SDag-Erling Smørgrav uint16_t opt_code; 228bc892140SDag-Erling Smørgrav /** whether the option needs to bypass the cache stage */ 229bc892140SDag-Erling Smørgrav int bypass_cache_stage; 230bc892140SDag-Erling Smørgrav /** whether the option needs mesh aggregation */ 231bc892140SDag-Erling Smørgrav int no_aggregation; 232bc892140SDag-Erling Smørgrav }; 233bc892140SDag-Erling Smørgrav 234bc892140SDag-Erling Smørgrav /** 23565b390aaSDag-Erling Smørgrav * Inplace callback list of registered routines to be called. 23665b390aaSDag-Erling Smørgrav */ 23765b390aaSDag-Erling Smørgrav struct inplace_cb { 23865b390aaSDag-Erling Smørgrav /** next in list */ 23965b390aaSDag-Erling Smørgrav struct inplace_cb* next; 24065b390aaSDag-Erling Smørgrav /** Inplace callback routine */ 24165b390aaSDag-Erling Smørgrav void* cb; 24265b390aaSDag-Erling Smørgrav void* cb_arg; 24365b390aaSDag-Erling Smørgrav /** module id */ 24465b390aaSDag-Erling Smørgrav int id; 24565b390aaSDag-Erling Smørgrav }; 24665b390aaSDag-Erling Smørgrav 24765b390aaSDag-Erling Smørgrav /** 248bc892140SDag-Erling Smørgrav * Inplace callback function called before replying. 2494c75e3aaSDag-Erling Smørgrav * Called as func(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, 2504c75e3aaSDag-Erling Smørgrav * region, id, python_callback) 251bc892140SDag-Erling Smørgrav * Where: 252bc892140SDag-Erling Smørgrav * qinfo: the query info. 253bc892140SDag-Erling Smørgrav * qstate: the module state. NULL when calling before the query reaches the 254bc892140SDag-Erling Smørgrav * mesh states. 255bc892140SDag-Erling Smørgrav * rep: reply_info. Could be NULL. 256bc892140SDag-Erling Smørgrav * rcode: the return code. 257bc892140SDag-Erling Smørgrav * edns: the edns_data of the reply. When qstate is NULL, it is also used as 258bc892140SDag-Erling Smørgrav * the edns input. 259bc892140SDag-Erling Smørgrav * opt_list_out: the edns options list for the reply. 2604c75e3aaSDag-Erling Smørgrav * repinfo: reply information for a communication point. NULL when calling 2614c75e3aaSDag-Erling Smørgrav * during the mesh states; the same could be found from 2624c75e3aaSDag-Erling Smørgrav * qstate->mesh_info->reply_list. 263bc892140SDag-Erling Smørgrav * region: region to store data. 2644c75e3aaSDag-Erling Smørgrav * id: module id. 265bc892140SDag-Erling Smørgrav * python_callback: only used for registering a python callback function. 266bc892140SDag-Erling Smørgrav */ 2673005e0a3SDag-Erling Smørgrav typedef int inplace_cb_reply_func_type(struct query_info* qinfo, 268bc892140SDag-Erling Smørgrav struct module_qstate* qstate, struct reply_info* rep, int rcode, 269bc892140SDag-Erling Smørgrav struct edns_data* edns, struct edns_option** opt_list_out, 270f44e67d1SCy Schubert struct comm_reply* repinfo, struct regional* region, 271f44e67d1SCy Schubert struct timeval* start_time, int id, void* callback); 272bc892140SDag-Erling Smørgrav 273bc892140SDag-Erling Smørgrav /** 274bc892140SDag-Erling Smørgrav * Inplace callback function called before sending the query to a nameserver. 275bc892140SDag-Erling Smørgrav * Called as func(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, 2764c75e3aaSDag-Erling Smørgrav * id, python_callback) 277bc892140SDag-Erling Smørgrav * Where: 278bc892140SDag-Erling Smørgrav * qinfo: query info. 279bc892140SDag-Erling Smørgrav * flags: flags of the query. 280bc892140SDag-Erling Smørgrav * qstate: query state. 281bc892140SDag-Erling Smørgrav * addr: to which server to send the query. 282bc892140SDag-Erling Smørgrav * addrlen: length of addr. 283bc892140SDag-Erling Smørgrav * zone: name of the zone of the delegation point. wireformat dname. 284bc892140SDag-Erling Smørgrav * This is the delegation point name for which the server is deemed 285bc892140SDag-Erling Smørgrav * authoritative. 286bc892140SDag-Erling Smørgrav * zonelen: length of zone. 287bc892140SDag-Erling Smørgrav * region: region to store data. 2884c75e3aaSDag-Erling Smørgrav * id: module id. 289bc892140SDag-Erling Smørgrav * python_callback: only used for registering a python callback function. 290bc892140SDag-Erling Smørgrav */ 2913005e0a3SDag-Erling Smørgrav typedef int inplace_cb_query_func_type(struct query_info* qinfo, uint16_t flags, 292bc892140SDag-Erling Smørgrav struct module_qstate* qstate, struct sockaddr_storage* addr, 293bc892140SDag-Erling Smørgrav socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region, 29465b390aaSDag-Erling Smørgrav int id, void* callback); 295bc892140SDag-Erling Smørgrav 296bc892140SDag-Erling Smørgrav /** 29765b390aaSDag-Erling Smørgrav * Inplace callback function called after parsing edns on query reply. 2984c75e3aaSDag-Erling Smørgrav * Called as func(qstate, id, cb_args) 29965b390aaSDag-Erling Smørgrav * Where: 3004c75e3aaSDag-Erling Smørgrav * qstate: the query state. 3014c75e3aaSDag-Erling Smørgrav * id: module id. 30265b390aaSDag-Erling Smørgrav * cb_args: argument passed when registering callback. 303bc892140SDag-Erling Smørgrav */ 30465b390aaSDag-Erling Smørgrav typedef int inplace_cb_edns_back_parsed_func_type(struct module_qstate* qstate, 30565b390aaSDag-Erling Smørgrav int id, void* cb_args); 30665b390aaSDag-Erling Smørgrav 307bc892140SDag-Erling Smørgrav /** 30865b390aaSDag-Erling Smørgrav * Inplace callback function called after parsing query response. 3094c75e3aaSDag-Erling Smørgrav * Called as func(qstate, response, id, cb_args) 31065b390aaSDag-Erling Smørgrav * Where: 3114c75e3aaSDag-Erling Smørgrav * qstate: the query state. 3124c75e3aaSDag-Erling Smørgrav * response: query response. 3134c75e3aaSDag-Erling Smørgrav * id: module id. 31465b390aaSDag-Erling Smørgrav * cb_args: argument passed when registering callback. 315bc892140SDag-Erling Smørgrav */ 31665b390aaSDag-Erling Smørgrav typedef int inplace_cb_query_response_func_type(struct module_qstate* qstate, 31765b390aaSDag-Erling Smørgrav struct dns_msg* response, int id, void* cb_args); 318bc892140SDag-Erling Smørgrav 319b7579f77SDag-Erling Smørgrav /** 320091e9e46SCy Schubert * Function called when looking for (expired) cached answers during the serve 321091e9e46SCy Schubert * expired logic. 322*46d2f618SCy Schubert * Called as func(qstate, lookup_qinfo, &is_expired) 323091e9e46SCy Schubert * Where: 324091e9e46SCy Schubert * qstate: the query state. 325091e9e46SCy Schubert * lookup_qinfo: the qinfo to lookup for. 326*46d2f618SCy Schubert * is_expired: set if the cached answer is expired. 327091e9e46SCy Schubert */ 328091e9e46SCy Schubert typedef struct dns_msg* serve_expired_lookup_func_type( 329*46d2f618SCy Schubert struct module_qstate* qstate, struct query_info* lookup_qinfo, 330*46d2f618SCy Schubert int* is_expired); 331091e9e46SCy Schubert 332091e9e46SCy Schubert /** 333b7579f77SDag-Erling Smørgrav * Module environment. 334b7579f77SDag-Erling Smørgrav * Services and data provided to the module. 335b7579f77SDag-Erling Smørgrav */ 336b7579f77SDag-Erling Smørgrav struct module_env { 337b7579f77SDag-Erling Smørgrav /* --- data --- */ 338b7579f77SDag-Erling Smørgrav /** config file with config options */ 339b7579f77SDag-Erling Smørgrav struct config_file* cfg; 340b7579f77SDag-Erling Smørgrav /** shared message cache */ 341b7579f77SDag-Erling Smørgrav struct slabhash* msg_cache; 342b7579f77SDag-Erling Smørgrav /** shared rrset cache */ 343b7579f77SDag-Erling Smørgrav struct rrset_cache* rrset_cache; 344b7579f77SDag-Erling Smørgrav /** shared infrastructure cache (edns, lameness) */ 345b7579f77SDag-Erling Smørgrav struct infra_cache* infra_cache; 346b7579f77SDag-Erling Smørgrav /** shared key cache */ 347b7579f77SDag-Erling Smørgrav struct key_cache* key_cache; 348b7579f77SDag-Erling Smørgrav 349b7579f77SDag-Erling Smørgrav /* --- services --- */ 350b7579f77SDag-Erling Smørgrav /** 351b7579f77SDag-Erling Smørgrav * Send serviced DNS query to server. UDP/TCP and EDNS is handled. 352b7579f77SDag-Erling Smørgrav * operate() should return with wait_reply. Later on a callback 353b7579f77SDag-Erling Smørgrav * will cause operate() to be called with event timeout or reply. 354b7579f77SDag-Erling Smørgrav * The time until a timeout is calculated from roundtrip timing, 355b7579f77SDag-Erling Smørgrav * several UDP retries are attempted. 356bc892140SDag-Erling Smørgrav * @param qinfo: query info. 357b7579f77SDag-Erling Smørgrav * @param flags: host order flags word, with opcode and CD bit. 358b7579f77SDag-Erling Smørgrav * @param dnssec: if set, EDNS record will have bits set. 359b7579f77SDag-Erling Smørgrav * If EDNS_DO bit is set, DO bit is set in EDNS records. 360b7579f77SDag-Erling Smørgrav * If BIT_CD is set, CD bit is set in queries with EDNS records. 361b7579f77SDag-Erling Smørgrav * @param want_dnssec: if set, the validator wants DNSSEC. Without 362b7579f77SDag-Erling Smørgrav * EDNS, the answer is likely to be useless for this domain. 363ff825849SDag-Erling Smørgrav * @param nocaps: do not use caps_for_id, use the qname as given. 364ff825849SDag-Erling Smørgrav * (ignored if caps_for_id is disabled). 3659cf5bc93SCy Schubert * @param check_ratelimit: if set, will check ratelimit before sending out. 366b7579f77SDag-Erling Smørgrav * @param addr: where to. 367b7579f77SDag-Erling Smørgrav * @param addrlen: length of addr. 368b7579f77SDag-Erling Smørgrav * @param zone: delegation point name. 369b7579f77SDag-Erling Smørgrav * @param zonelen: length of zone name. 37024e36522SCy Schubert * @param tcp_upstream: use TCP for upstream queries. 371bc892140SDag-Erling Smørgrav * @param ssl_upstream: use SSL for upstream queries. 3720fb34990SDag-Erling Smørgrav * @param tls_auth_name: if ssl_upstream, use this name with TLS 3730fb34990SDag-Erling Smørgrav * authentication. 37424e36522SCy Schubert * @param q: which query state to reactivate upon return. 3759cf5bc93SCy Schubert * @param was_ratelimited: it will signal back if the query failed to pass the 3769cf5bc93SCy Schubert * ratelimit check. 377b7579f77SDag-Erling Smørgrav * @return: false on failure (memory or socket related). no query was 378b7579f77SDag-Erling Smørgrav * sent. Or returns an outbound entry with qsent and qstate set. 379b7579f77SDag-Erling Smørgrav * This outbound_entry will be used on later module invocations 380b7579f77SDag-Erling Smørgrav * that involve this query (timeout, error or reply). 381b7579f77SDag-Erling Smørgrav */ 382bc892140SDag-Erling Smørgrav struct outbound_entry* (*send_query)(struct query_info* qinfo, 383bc892140SDag-Erling Smørgrav uint16_t flags, int dnssec, int want_dnssec, int nocaps, 3849cf5bc93SCy Schubert int check_ratelimit, 385e2d15004SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, 38624e36522SCy Schubert uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, 3879cf5bc93SCy Schubert char* tls_auth_name, struct module_qstate* q, int* was_ratelimited); 388b7579f77SDag-Erling Smørgrav 389b7579f77SDag-Erling Smørgrav /** 390b7579f77SDag-Erling Smørgrav * Detach-subqueries. 391b7579f77SDag-Erling Smørgrav * Remove all sub-query references from this query state. 392b7579f77SDag-Erling Smørgrav * Keeps super-references of those sub-queries correct. 393b7579f77SDag-Erling Smørgrav * Updates stat items in mesh_area structure. 394b7579f77SDag-Erling Smørgrav * @param qstate: used to find mesh state. 395b7579f77SDag-Erling Smørgrav */ 396b7579f77SDag-Erling Smørgrav void (*detach_subs)(struct module_qstate* qstate); 397b7579f77SDag-Erling Smørgrav 398b7579f77SDag-Erling Smørgrav /** 399b7579f77SDag-Erling Smørgrav * Attach subquery. 400b7579f77SDag-Erling Smørgrav * Creates it if it does not exist already. 401b7579f77SDag-Erling Smørgrav * Keeps sub and super references correct. 402b7579f77SDag-Erling Smørgrav * Updates stat items in mesh_area structure. 403b7579f77SDag-Erling Smørgrav * Pass if it is priming query or not. 404b7579f77SDag-Erling Smørgrav * return: 405b7579f77SDag-Erling Smørgrav * o if error (malloc) happened. 406b7579f77SDag-Erling Smørgrav * o need to initialise the new state (module init; it is a new state). 407b7579f77SDag-Erling Smørgrav * so that the next run of the query with this module is successful. 408b7579f77SDag-Erling Smørgrav * o no init needed, attachment successful. 409b7579f77SDag-Erling Smørgrav * 410b7579f77SDag-Erling Smørgrav * @param qstate: the state to find mesh state, and that wants to 411b7579f77SDag-Erling Smørgrav * receive the results from the new subquery. 412b7579f77SDag-Erling Smørgrav * @param qinfo: what to query for (copied). 413b7579f77SDag-Erling Smørgrav * @param qflags: what flags to use (RD, CD flag or not). 414b7579f77SDag-Erling Smørgrav * @param prime: if it is a (stub) priming query. 415ff825849SDag-Erling Smørgrav * @param valrec: validation lookup recursion, does not need validation 416b7579f77SDag-Erling Smørgrav * @param newq: If the new subquery needs initialisation, it is 417b7579f77SDag-Erling Smørgrav * returned, otherwise NULL is returned. 418b7579f77SDag-Erling Smørgrav * @return: false on error, true if success (and init may be needed). 419b7579f77SDag-Erling Smørgrav */ 420b7579f77SDag-Erling Smørgrav int (*attach_sub)(struct module_qstate* qstate, 421b7579f77SDag-Erling Smørgrav struct query_info* qinfo, uint16_t qflags, int prime, 422ff825849SDag-Erling Smørgrav int valrec, struct module_qstate** newq); 423b7579f77SDag-Erling Smørgrav 424b7579f77SDag-Erling Smørgrav /** 425c7f4d7adSDag-Erling Smørgrav * Add detached query. 426c7f4d7adSDag-Erling Smørgrav * Creates it if it does not exist already. 427c7f4d7adSDag-Erling Smørgrav * Does not make super/sub references. 428c7f4d7adSDag-Erling Smørgrav * Performs a cycle detection - for double check - and fails if there is 429c7f4d7adSDag-Erling Smørgrav * one. 430c7f4d7adSDag-Erling Smørgrav * Updates stat items in mesh_area structure. 431c7f4d7adSDag-Erling Smørgrav * Pass if it is priming query or not. 432c7f4d7adSDag-Erling Smørgrav * return: 433c7f4d7adSDag-Erling Smørgrav * o if error (malloc) happened. 434c7f4d7adSDag-Erling Smørgrav * o need to initialise the new state (module init; it is a new state). 435c7f4d7adSDag-Erling Smørgrav * so that the next run of the query with this module is successful. 436c7f4d7adSDag-Erling Smørgrav * o no init needed, attachment successful. 437c7f4d7adSDag-Erling Smørgrav * o added subquery, created if it did not exist already. 438c7f4d7adSDag-Erling Smørgrav * 439c7f4d7adSDag-Erling Smørgrav * @param qstate: the state to find mesh state, and that wants to receive 440c7f4d7adSDag-Erling Smørgrav * the results from the new subquery. 441c7f4d7adSDag-Erling Smørgrav * @param qinfo: what to query for (copied). 442c7f4d7adSDag-Erling Smørgrav * @param qflags: what flags to use (RD / CD flag or not). 443c7f4d7adSDag-Erling Smørgrav * @param prime: if it is a (stub) priming query. 444c7f4d7adSDag-Erling Smørgrav * @param valrec: if it is a validation recursion query (lookup of key, DS). 445c7f4d7adSDag-Erling Smørgrav * @param newq: If the new subquery needs initialisation, it is returned, 446c7f4d7adSDag-Erling Smørgrav * otherwise NULL is returned. 447c7f4d7adSDag-Erling Smørgrav * @param sub: The added mesh state, created if it did not exist already. 448c7f4d7adSDag-Erling Smørgrav * @return: false on error, true if success (and init may be needed). 449c7f4d7adSDag-Erling Smørgrav */ 450c7f4d7adSDag-Erling Smørgrav int (*add_sub)(struct module_qstate* qstate, 451c7f4d7adSDag-Erling Smørgrav struct query_info* qinfo, uint16_t qflags, int prime, 452c7f4d7adSDag-Erling Smørgrav int valrec, struct module_qstate** newq, 453c7f4d7adSDag-Erling Smørgrav struct mesh_state** sub); 454c7f4d7adSDag-Erling Smørgrav 455c7f4d7adSDag-Erling Smørgrav /** 456b7579f77SDag-Erling Smørgrav * Kill newly attached sub. If attach_sub returns newq for 457b7579f77SDag-Erling Smørgrav * initialisation, but that fails, then this routine will cleanup and 4588a384985SDag-Erling Smørgrav * delete the freshly created sub. 459b7579f77SDag-Erling Smørgrav * @param newq: the new subquery that is no longer needed. 460b7579f77SDag-Erling Smørgrav * It is removed. 461b7579f77SDag-Erling Smørgrav */ 462b7579f77SDag-Erling Smørgrav void (*kill_sub)(struct module_qstate* newq); 463b7579f77SDag-Erling Smørgrav 464b7579f77SDag-Erling Smørgrav /** 465b7579f77SDag-Erling Smørgrav * Detect if adding a dependency for qstate on name,type,class will 466b7579f77SDag-Erling Smørgrav * create a dependency cycle. 467b7579f77SDag-Erling Smørgrav * @param qstate: given mesh querystate. 468b7579f77SDag-Erling Smørgrav * @param qinfo: query info for dependency. 469b7579f77SDag-Erling Smørgrav * @param flags: query flags of dependency, RD/CD flags. 470b7579f77SDag-Erling Smørgrav * @param prime: if dependency is a priming query or not. 471ff825849SDag-Erling Smørgrav * @param valrec: validation lookup recursion, does not need validation 472b7579f77SDag-Erling Smørgrav * @return true if the name,type,class exists and the given 473b7579f77SDag-Erling Smørgrav * qstate mesh exists as a dependency of that name. Thus 474b7579f77SDag-Erling Smørgrav * if qstate becomes dependent on name,type,class then a 475b7579f77SDag-Erling Smørgrav * cycle is created. 476b7579f77SDag-Erling Smørgrav */ 477b7579f77SDag-Erling Smørgrav int (*detect_cycle)(struct module_qstate* qstate, 478ff825849SDag-Erling Smørgrav struct query_info* qinfo, uint16_t flags, int prime, 479ff825849SDag-Erling Smørgrav int valrec); 480b7579f77SDag-Erling Smørgrav 481b7579f77SDag-Erling Smørgrav /** region for temporary usage. May be cleared after operate() call. */ 482b7579f77SDag-Erling Smørgrav struct regional* scratch; 483b7579f77SDag-Erling Smørgrav /** buffer for temporary usage. May be cleared after operate() call. */ 48417d15b25SDag-Erling Smørgrav struct sldns_buffer* scratch_buffer; 485b7579f77SDag-Erling Smørgrav /** internal data for daemon - worker thread. */ 486b7579f77SDag-Erling Smørgrav struct worker* worker; 48757bddd21SDag-Erling Smørgrav /** the worker event base */ 48857bddd21SDag-Erling Smørgrav struct comm_base* worker_base; 48957bddd21SDag-Erling Smørgrav /** the outside network */ 49057bddd21SDag-Erling Smørgrav struct outside_network* outnet; 491b7579f77SDag-Erling Smørgrav /** mesh area with query state dependencies */ 492b7579f77SDag-Erling Smørgrav struct mesh_area* mesh; 493b7579f77SDag-Erling Smørgrav /** allocation service */ 494b7579f77SDag-Erling Smørgrav struct alloc_cache* alloc; 495b7579f77SDag-Erling Smørgrav /** random table to generate random numbers */ 496b7579f77SDag-Erling Smørgrav struct ub_randstate* rnd; 497b7579f77SDag-Erling Smørgrav /** time in seconds, converted to integer */ 49817d15b25SDag-Erling Smørgrav time_t* now; 499b7579f77SDag-Erling Smørgrav /** time in microseconds. Relatively recent. */ 500b7579f77SDag-Erling Smørgrav struct timeval* now_tv; 501b7579f77SDag-Erling Smørgrav /** is validation required for messages, controls client-facing 502b7579f77SDag-Erling Smørgrav * validation status (AD bits) and servfails */ 503b7579f77SDag-Erling Smørgrav int need_to_validate; 504b7579f77SDag-Erling Smørgrav /** trusted key storage; these are the configured keys, if not NULL, 505b7579f77SDag-Erling Smørgrav * otherwise configured by validator. These are the trust anchors, 506b7579f77SDag-Erling Smørgrav * and are not primed and ready for validation, but on the bright 507b7579f77SDag-Erling Smørgrav * side, they are read only memory, thus no locks and fast. */ 508b7579f77SDag-Erling Smørgrav struct val_anchors* anchors; 509b7579f77SDag-Erling Smørgrav /** negative cache, configured by the validator. if not NULL, 510b7579f77SDag-Erling Smørgrav * contains NSEC record lookup trees. */ 511b7579f77SDag-Erling Smørgrav struct val_neg_cache* neg_cache; 512b7579f77SDag-Erling Smørgrav /** the 5011-probe timer (if any) */ 513b7579f77SDag-Erling Smørgrav struct comm_timer* probe_timer; 51457bddd21SDag-Erling Smørgrav /** auth zones */ 51557bddd21SDag-Erling Smørgrav struct auth_zones* auth_zones; 516b7579f77SDag-Erling Smørgrav /** Mapping of forwarding zones to targets. 517335c7cdaSCy Schubert * iterator forwarder information. */ 518b7579f77SDag-Erling Smørgrav struct iter_forwards* fwds; 519b7579f77SDag-Erling Smørgrav /** 520335c7cdaSCy Schubert * iterator stub information. 521b7579f77SDag-Erling Smørgrav * The hints -- these aren't stored in the cache because they don't 522b7579f77SDag-Erling Smørgrav * expire. The hints are always used to "prime" the cache. Note 523b7579f77SDag-Erling Smørgrav * that both root hints and stub zone "hints" are stored in this 524b7579f77SDag-Erling Smørgrav * data structure. 525b7579f77SDag-Erling Smørgrav */ 526b7579f77SDag-Erling Smørgrav struct iter_hints* hints; 527b7579f77SDag-Erling Smørgrav /** module specific data. indexed by module id. */ 528b7579f77SDag-Erling Smørgrav void* modinfo[MAX_MODULE]; 529bc892140SDag-Erling Smørgrav 530bc892140SDag-Erling Smørgrav /* Shared linked list of inplace callback functions */ 53165b390aaSDag-Erling Smørgrav struct inplace_cb* inplace_cb_lists[inplace_cb_types_total]; 532bc892140SDag-Erling Smørgrav 533bc892140SDag-Erling Smørgrav /** 534bc892140SDag-Erling Smørgrav * Shared array of known edns options (size MAX_KNOWN_EDNS_OPTS). 535bc892140SDag-Erling Smørgrav * Filled by edns literate modules during init. 536bc892140SDag-Erling Smørgrav */ 537bc892140SDag-Erling Smørgrav struct edns_known_option* edns_known_options; 538bc892140SDag-Erling Smørgrav /* Number of known edns options */ 539bc892140SDag-Erling Smørgrav size_t edns_known_options_num; 540369c6923SCy Schubert /** EDNS client string information */ 541369c6923SCy Schubert struct edns_strings* edns_strings; 54265b390aaSDag-Erling Smørgrav 543335c7cdaSCy Schubert /** module stack */ 544335c7cdaSCy Schubert struct module_stack* modstack; 545335c7cdaSCy Schubert #ifdef USE_CACHEDB 546335c7cdaSCy Schubert /** the cachedb enabled value, copied and stored here. */ 547335c7cdaSCy Schubert int cachedb_enabled; 548335c7cdaSCy Schubert #endif 54965b390aaSDag-Erling Smørgrav /* Make every mesh state unique, do not aggregate mesh states. */ 55065b390aaSDag-Erling Smørgrav int unique_mesh; 551b7579f77SDag-Erling Smørgrav }; 552b7579f77SDag-Erling Smørgrav 553b7579f77SDag-Erling Smørgrav /** 554b7579f77SDag-Erling Smørgrav * External visible states of the module state machine 555b7579f77SDag-Erling Smørgrav * Modules may also have an internal state. 556b7579f77SDag-Erling Smørgrav * Modules are supposed to run to completion or until blocked. 557b7579f77SDag-Erling Smørgrav */ 558b7579f77SDag-Erling Smørgrav enum module_ext_state { 559b7579f77SDag-Erling Smørgrav /** initial state - new query */ 560b7579f77SDag-Erling Smørgrav module_state_initial = 0, 561b7579f77SDag-Erling Smørgrav /** waiting for reply to outgoing network query */ 562b7579f77SDag-Erling Smørgrav module_wait_reply, 563b7579f77SDag-Erling Smørgrav /** module is waiting for another module */ 564b7579f77SDag-Erling Smørgrav module_wait_module, 565b7579f77SDag-Erling Smørgrav /** module is waiting for another module; that other is restarted */ 566b7579f77SDag-Erling Smørgrav module_restart_next, 567b7579f77SDag-Erling Smørgrav /** module is waiting for sub-query */ 568b7579f77SDag-Erling Smørgrav module_wait_subquery, 569b7579f77SDag-Erling Smørgrav /** module could not finish the query */ 570b7579f77SDag-Erling Smørgrav module_error, 571b7579f77SDag-Erling Smørgrav /** module is finished with query */ 572b7579f77SDag-Erling Smørgrav module_finished 573b7579f77SDag-Erling Smørgrav }; 574b7579f77SDag-Erling Smørgrav 575b7579f77SDag-Erling Smørgrav /** 576b7579f77SDag-Erling Smørgrav * Events that happen to modules, that start or wakeup modules. 577b7579f77SDag-Erling Smørgrav */ 578b7579f77SDag-Erling Smørgrav enum module_ev { 579b7579f77SDag-Erling Smørgrav /** new query */ 580b7579f77SDag-Erling Smørgrav module_event_new = 0, 581b7579f77SDag-Erling Smørgrav /** query passed by other module */ 582b7579f77SDag-Erling Smørgrav module_event_pass, 583b7579f77SDag-Erling Smørgrav /** reply inbound from server */ 584b7579f77SDag-Erling Smørgrav module_event_reply, 585b7579f77SDag-Erling Smørgrav /** no reply, timeout or other error */ 586b7579f77SDag-Erling Smørgrav module_event_noreply, 587b7579f77SDag-Erling Smørgrav /** reply is there, but capitalisation check failed */ 588b7579f77SDag-Erling Smørgrav module_event_capsfail, 589b7579f77SDag-Erling Smørgrav /** next module is done, and its reply is awaiting you */ 590b7579f77SDag-Erling Smørgrav module_event_moddone, 591b7579f77SDag-Erling Smørgrav /** error */ 592b7579f77SDag-Erling Smørgrav module_event_error 593b7579f77SDag-Erling Smørgrav }; 594b7579f77SDag-Erling Smørgrav 595b7579f77SDag-Erling Smørgrav /** 596b7579f77SDag-Erling Smørgrav * Linked list of sockaddrs 597b7579f77SDag-Erling Smørgrav * May be allocated such that only 'len' bytes of addr exist for the structure. 598b7579f77SDag-Erling Smørgrav */ 599b7579f77SDag-Erling Smørgrav struct sock_list { 600b7579f77SDag-Erling Smørgrav /** next in list */ 601b7579f77SDag-Erling Smørgrav struct sock_list* next; 602b7579f77SDag-Erling Smørgrav /** length of addr */ 603b7579f77SDag-Erling Smørgrav socklen_t len; 604b7579f77SDag-Erling Smørgrav /** sockaddr */ 605b7579f77SDag-Erling Smørgrav struct sockaddr_storage addr; 606b7579f77SDag-Erling Smørgrav }; 607b7579f77SDag-Erling Smørgrav 60865b390aaSDag-Erling Smørgrav struct respip_action_info; 60965b390aaSDag-Erling Smørgrav 610b7579f77SDag-Erling Smørgrav /** 611091e9e46SCy Schubert * Struct to hold relevant data for serve expired 612091e9e46SCy Schubert */ 613091e9e46SCy Schubert struct serve_expired_data { 614091e9e46SCy Schubert struct comm_timer* timer; 615091e9e46SCy Schubert serve_expired_lookup_func_type* get_cached_answer; 616091e9e46SCy Schubert }; 617091e9e46SCy Schubert 618091e9e46SCy Schubert /** 619b7579f77SDag-Erling Smørgrav * Module state, per query. 620b7579f77SDag-Erling Smørgrav */ 621b7579f77SDag-Erling Smørgrav struct module_qstate { 622b7579f77SDag-Erling Smørgrav /** which query is being answered: name, type, class */ 623b7579f77SDag-Erling Smørgrav struct query_info qinfo; 624b7579f77SDag-Erling Smørgrav /** flags uint16 from query */ 625b7579f77SDag-Erling Smørgrav uint16_t query_flags; 626b7579f77SDag-Erling Smørgrav /** if this is a (stub or root) priming query (with hints) */ 627b7579f77SDag-Erling Smørgrav int is_priming; 628ff825849SDag-Erling Smørgrav /** if this is a validation recursion query that does not get 629ff825849SDag-Erling Smørgrav * validation itself */ 630ff825849SDag-Erling Smørgrav int is_valrec; 6318f76bb7dSCy Schubert #ifdef CLIENT_SUBNET 6328f76bb7dSCy Schubert /** the client network address is needed for the client-subnet option 6338f76bb7dSCy Schubert * when prefetching, but we can't use reply_list in mesh_info, because 6348f76bb7dSCy Schubert * we don't want to send a reply for the internal query. */ 6358f76bb7dSCy Schubert struct sockaddr_storage client_addr; 6368f76bb7dSCy Schubert #endif 637b7579f77SDag-Erling Smørgrav 638b7579f77SDag-Erling Smørgrav /** comm_reply contains server replies */ 639b7579f77SDag-Erling Smørgrav struct comm_reply* reply; 640b7579f77SDag-Erling Smørgrav /** the reply message, with message for client and calling module */ 641b7579f77SDag-Erling Smørgrav struct dns_msg* return_msg; 642b7579f77SDag-Erling Smørgrav /** the rcode, in case of error, instead of a reply message */ 643b7579f77SDag-Erling Smørgrav int return_rcode; 644b7579f77SDag-Erling Smørgrav /** origin of the reply (can be NULL from cache, list for cnames) */ 645b7579f77SDag-Erling Smørgrav struct sock_list* reply_origin; 646b7579f77SDag-Erling Smørgrav /** IP blacklist for queries */ 647b7579f77SDag-Erling Smørgrav struct sock_list* blacklist; 648b7579f77SDag-Erling Smørgrav /** region for this query. Cleared when query process finishes. */ 649b7579f77SDag-Erling Smørgrav struct regional* region; 650b7579f77SDag-Erling Smørgrav /** failure reason information if val-log-level is high */ 651a39a5a69SCy Schubert struct errinf_strlist* errinf; 652b7579f77SDag-Erling Smørgrav /** which module is executing */ 653b7579f77SDag-Erling Smørgrav int curmod; 654b7579f77SDag-Erling Smørgrav /** module states */ 655b7579f77SDag-Erling Smørgrav enum module_ext_state ext_state[MAX_MODULE]; 656b7579f77SDag-Erling Smørgrav /** module specific data for query. indexed by module id. */ 657b7579f77SDag-Erling Smørgrav void* minfo[MAX_MODULE]; 658b7579f77SDag-Erling Smørgrav /** environment for this query */ 659b7579f77SDag-Erling Smørgrav struct module_env* env; 660b7579f77SDag-Erling Smørgrav /** mesh related information for this query */ 661b7579f77SDag-Erling Smørgrav struct mesh_state* mesh_info; 662b7579f77SDag-Erling Smørgrav /** how many seconds before expiry is this prefetched (0 if not) */ 66317d15b25SDag-Erling Smørgrav time_t prefetch_leeway; 664091e9e46SCy Schubert /** serve expired data */ 665091e9e46SCy Schubert struct serve_expired_data* serve_expired_data; 666bc892140SDag-Erling Smørgrav 667bc892140SDag-Erling Smørgrav /** incoming edns options from the front end */ 668bc892140SDag-Erling Smørgrav struct edns_option* edns_opts_front_in; 669bc892140SDag-Erling Smørgrav /** outgoing edns options to the back end */ 670bc892140SDag-Erling Smørgrav struct edns_option* edns_opts_back_out; 671bc892140SDag-Erling Smørgrav /** incoming edns options from the back end */ 672bc892140SDag-Erling Smørgrav struct edns_option* edns_opts_back_in; 673bc892140SDag-Erling Smørgrav /** outgoing edns options to the front end */ 674bc892140SDag-Erling Smørgrav struct edns_option* edns_opts_front_out; 675bc892140SDag-Erling Smørgrav /** whether modules should answer from the cache */ 676bc892140SDag-Erling Smørgrav int no_cache_lookup; 677bc892140SDag-Erling Smørgrav /** whether modules should store answer in the cache */ 678bc892140SDag-Erling Smørgrav int no_cache_store; 6798a384985SDag-Erling Smørgrav /** whether to refetch a fresh answer on finishing this state*/ 6808a384985SDag-Erling Smørgrav int need_refetch; 6814c75e3aaSDag-Erling Smørgrav /** whether the query (or a subquery) was ratelimited */ 6824c75e3aaSDag-Erling Smørgrav int was_ratelimited; 683790c6b24SCy Schubert /** time when query was started. This is when the qstate is created. 684790c6b24SCy Schubert * This is used so that type NS data cannot be overwritten by them 685790c6b24SCy Schubert * expiring while the lookup is in progress, using data fetched from 686790c6b24SCy Schubert * those servers. By comparing expiry time with qstarttime for type NS. 687790c6b24SCy Schubert */ 688790c6b24SCy Schubert time_t qstarttime; 6898f76bb7dSCy Schubert /** whether a message from cachedb will be used for the reply */ 6908f76bb7dSCy Schubert int is_cachedb_answer; 69165b390aaSDag-Erling Smørgrav 69265b390aaSDag-Erling Smørgrav /** 69365b390aaSDag-Erling Smørgrav * Attributes of clients that share the qstate that may affect IP-based 69465b390aaSDag-Erling Smørgrav * actions. 69565b390aaSDag-Erling Smørgrav */ 69665b390aaSDag-Erling Smørgrav struct respip_client_info* client_info; 69765b390aaSDag-Erling Smørgrav 69865b390aaSDag-Erling Smørgrav /** Extended result of response-ip action processing, mainly 69965b390aaSDag-Erling Smørgrav * for logging purposes. */ 70065b390aaSDag-Erling Smørgrav struct respip_action_info* respip_action_info; 701*46d2f618SCy Schubert /** if the query has been modified by rpz processing. */ 702*46d2f618SCy Schubert int rpz_applied; 703a39a5a69SCy Schubert /** if the query is rpz passthru, no further rpz processing for it */ 704a39a5a69SCy Schubert int rpz_passthru; 705103ba509SCy Schubert /* Flag tcp required. */ 706103ba509SCy Schubert int tcp_required; 70765b390aaSDag-Erling Smørgrav 70865b390aaSDag-Erling Smørgrav /** whether the reply should be dropped */ 70965b390aaSDag-Erling Smørgrav int is_drop; 710b7579f77SDag-Erling Smørgrav }; 711b7579f77SDag-Erling Smørgrav 712b7579f77SDag-Erling Smørgrav /** 713b7579f77SDag-Erling Smørgrav * Module functionality block 714b7579f77SDag-Erling Smørgrav */ 715b7579f77SDag-Erling Smørgrav struct module_func_block { 716b7579f77SDag-Erling Smørgrav /** text string name of module */ 717b7579f77SDag-Erling Smørgrav const char* name; 718b7579f77SDag-Erling Smørgrav 719b7579f77SDag-Erling Smørgrav /** 72056850988SCy Schubert * Set up the module for start. This is called only once at startup. 72156850988SCy Schubert * Privileged operations like opening device files may be done here. 72256850988SCy Schubert * The function ptr can be NULL, if it is not used. 72356850988SCy Schubert * @param env: module environment. 72456850988SCy Schubert * @param id: module id number. 72556850988SCy Schubert * return: 0 on error 72656850988SCy Schubert */ 72756850988SCy Schubert int (*startup)(struct module_env* env, int id); 72856850988SCy Schubert 72956850988SCy Schubert /** 73056850988SCy Schubert * Close down the module for stop. This is called only once before 73156850988SCy Schubert * shutdown to free resources allocated during startup(). 73256850988SCy Schubert * Closing privileged ports or files must be done here. 73356850988SCy Schubert * The function ptr can be NULL, if it is not used. 73456850988SCy Schubert * @param env: module environment. 73556850988SCy Schubert * @param id: module id number. 73656850988SCy Schubert */ 73756850988SCy Schubert void (*destartup)(struct module_env* env, int id); 73856850988SCy Schubert 73956850988SCy Schubert /** 74056850988SCy Schubert * Initialise the module. Called when restarting or reloading the 74156850988SCy Schubert * daemon. 742b7579f77SDag-Erling Smørgrav * This is the place to apply settings from the config file. 743b7579f77SDag-Erling Smørgrav * @param env: module environment. 744b7579f77SDag-Erling Smørgrav * @param id: module id number. 745b7579f77SDag-Erling Smørgrav * return: 0 on error 746b7579f77SDag-Erling Smørgrav */ 747b7579f77SDag-Erling Smørgrav int (*init)(struct module_env* env, int id); 748b7579f77SDag-Erling Smørgrav 749b7579f77SDag-Erling Smørgrav /** 75056850988SCy Schubert * Deinitialise the module, undo stuff done during init(). 75156850988SCy Schubert * Called before reloading the daemon. 752b7579f77SDag-Erling Smørgrav * @param env: module environment. 753b7579f77SDag-Erling Smørgrav * @param id: module id number. 754b7579f77SDag-Erling Smørgrav */ 755b7579f77SDag-Erling Smørgrav void (*deinit)(struct module_env* env, int id); 756b7579f77SDag-Erling Smørgrav 757b7579f77SDag-Erling Smørgrav /** 758b7579f77SDag-Erling Smørgrav * accept a new query, or work further on existing query. 759b7579f77SDag-Erling Smørgrav * Changes the qstate->ext_state to be correct on exit. 760b7579f77SDag-Erling Smørgrav * @param ev: event that causes the module state machine to 761b7579f77SDag-Erling Smørgrav * (re-)activate. 762b7579f77SDag-Erling Smørgrav * @param qstate: the query state. 763b7579f77SDag-Erling Smørgrav * Note that this method is not allowed to change the 764b7579f77SDag-Erling Smørgrav * query state 'identity', that is query info, qflags, 765b7579f77SDag-Erling Smørgrav * and priming status. 766b7579f77SDag-Erling Smørgrav * Attach a subquery to get results to a different query. 767b7579f77SDag-Erling Smørgrav * @param id: module id number that operate() is called on. 768b7579f77SDag-Erling Smørgrav * @param outbound: if not NULL this event is due to the reply/timeout 769b7579f77SDag-Erling Smørgrav * or error on this outbound query. 770b7579f77SDag-Erling Smørgrav * @return: if at exit the ext_state is: 771b7579f77SDag-Erling Smørgrav * o wait_module: next module is started. (with pass event). 772b7579f77SDag-Erling Smørgrav * o error or finished: previous module is resumed. 773b7579f77SDag-Erling Smørgrav * o otherwise it waits until that event happens (assumes 774b7579f77SDag-Erling Smørgrav * the service routine to make subrequest or send message 775b7579f77SDag-Erling Smørgrav * have been called. 776b7579f77SDag-Erling Smørgrav */ 777b7579f77SDag-Erling Smørgrav void (*operate)(struct module_qstate* qstate, enum module_ev event, 778b7579f77SDag-Erling Smørgrav int id, struct outbound_entry* outbound); 779b7579f77SDag-Erling Smørgrav 780b7579f77SDag-Erling Smørgrav /** 781b7579f77SDag-Erling Smørgrav * inform super querystate about the results from this subquerystate. 782b7579f77SDag-Erling Smørgrav * Is called when the querystate is finished. The method invoked is 783b7579f77SDag-Erling Smørgrav * the one from the current module active in the super querystate. 784b7579f77SDag-Erling Smørgrav * @param qstate: the query state that is finished. 785b7579f77SDag-Erling Smørgrav * Examine return_rcode and return_reply in the qstate. 786b7579f77SDag-Erling Smørgrav * @param id: module id for this module. 787b7579f77SDag-Erling Smørgrav * This coincides with the current module for the super qstate. 788b7579f77SDag-Erling Smørgrav * @param super: the super querystate that needs to be informed. 789b7579f77SDag-Erling Smørgrav */ 790b7579f77SDag-Erling Smørgrav void (*inform_super)(struct module_qstate* qstate, int id, 791b7579f77SDag-Erling Smørgrav struct module_qstate* super); 792b7579f77SDag-Erling Smørgrav 793b7579f77SDag-Erling Smørgrav /** 794b7579f77SDag-Erling Smørgrav * clear module specific data 795b7579f77SDag-Erling Smørgrav */ 796b7579f77SDag-Erling Smørgrav void (*clear)(struct module_qstate* qstate, int id); 797b7579f77SDag-Erling Smørgrav 798b7579f77SDag-Erling Smørgrav /** 799b7579f77SDag-Erling Smørgrav * How much memory is the module specific data using. 800b7579f77SDag-Erling Smørgrav * @param env: module environment. 801b7579f77SDag-Erling Smørgrav * @param id: the module id. 802b7579f77SDag-Erling Smørgrav * @return the number of bytes that are alloced. 803b7579f77SDag-Erling Smørgrav */ 804b7579f77SDag-Erling Smørgrav size_t (*get_mem)(struct module_env* env, int id); 805b7579f77SDag-Erling Smørgrav }; 806b7579f77SDag-Erling Smørgrav 807b7579f77SDag-Erling Smørgrav /** 808b7579f77SDag-Erling Smørgrav * Debug utility: module external qstate to string 809b7579f77SDag-Erling Smørgrav * @param s: the state value. 810b7579f77SDag-Erling Smørgrav * @return descriptive string. 811b7579f77SDag-Erling Smørgrav */ 812b7579f77SDag-Erling Smørgrav const char* strextstate(enum module_ext_state s); 813b7579f77SDag-Erling Smørgrav 814b7579f77SDag-Erling Smørgrav /** 815b7579f77SDag-Erling Smørgrav * Debug utility: module event to string 816b7579f77SDag-Erling Smørgrav * @param e: the module event value. 817b7579f77SDag-Erling Smørgrav * @return descriptive string. 818b7579f77SDag-Erling Smørgrav */ 819b7579f77SDag-Erling Smørgrav const char* strmodulevent(enum module_ev e); 820b7579f77SDag-Erling Smørgrav 821bc892140SDag-Erling Smørgrav /** 822a39a5a69SCy Schubert * Append text to the error info for validation. 823a39a5a69SCy Schubert * @param qstate: query state. 824a39a5a69SCy Schubert * @param str: copied into query region and appended. 825a39a5a69SCy Schubert * Failures to allocate are logged. 826a39a5a69SCy Schubert */ 827a39a5a69SCy Schubert void errinf(struct module_qstate* qstate, const char* str); 828a39a5a69SCy Schubert void errinf_ede(struct module_qstate* qstate, const char* str, 829a39a5a69SCy Schubert sldns_ede_code reason_bogus); 830a39a5a69SCy Schubert 831a39a5a69SCy Schubert /** 832a39a5a69SCy Schubert * Append text to error info: from 1.2.3.4 833a39a5a69SCy Schubert * @param qstate: query state. 834a39a5a69SCy Schubert * @param origin: sock list with origin of trouble. 835a39a5a69SCy Schubert * Every element added. 836a39a5a69SCy Schubert * If NULL: nothing is added. 837a39a5a69SCy Schubert * if 0len element: 'from cache' is added. 838a39a5a69SCy Schubert */ 839a39a5a69SCy Schubert void errinf_origin(struct module_qstate* qstate, struct sock_list *origin); 840a39a5a69SCy Schubert 841a39a5a69SCy Schubert /** 842a39a5a69SCy Schubert * Append text to error info: for RRset name type class 843a39a5a69SCy Schubert * @param qstate: query state. 844a39a5a69SCy Schubert * @param rr: rrset_key. 845a39a5a69SCy Schubert */ 846a39a5a69SCy Schubert void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr); 847a39a5a69SCy Schubert 848a39a5a69SCy Schubert /** 849a39a5a69SCy Schubert * Append text to error info: str dname 850a39a5a69SCy Schubert * @param qstate: query state. 851a39a5a69SCy Schubert * @param str: explanation string 852a39a5a69SCy Schubert * @param dname: the dname. 853a39a5a69SCy Schubert */ 854a39a5a69SCy Schubert void errinf_dname(struct module_qstate* qstate, const char* str, 855a39a5a69SCy Schubert uint8_t* dname); 856a39a5a69SCy Schubert 857a39a5a69SCy Schubert /** 858a39a5a69SCy Schubert * Create error info in string. For validation failures. 859a39a5a69SCy Schubert * @param qstate: query state. 860335c7cdaSCy Schubert * @param region: the region for the result or NULL for malloced result. 861a39a5a69SCy Schubert * @return string or NULL on malloc failure (already logged). 862335c7cdaSCy Schubert * This string is malloced if region is NULL and has to be freed by caller. 863a39a5a69SCy Schubert */ 864335c7cdaSCy Schubert char* errinf_to_str_bogus(struct module_qstate* qstate, struct regional* region); 8658f76bb7dSCy Schubert 866a39a5a69SCy Schubert /** 8678f76bb7dSCy Schubert * Check the sldns_ede_code of the qstate->errinf. 868a39a5a69SCy Schubert * @param qstate: query state. 8698f76bb7dSCy Schubert * @return the latest explicitly set sldns_ede_code or LDNS_EDE_NONE. 870a39a5a69SCy Schubert */ 871a39a5a69SCy Schubert sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate); 872a39a5a69SCy Schubert 873a39a5a69SCy Schubert /** 874a39a5a69SCy Schubert * Create error info in string. For other servfails. 875a39a5a69SCy Schubert * @param qstate: query state. 876a39a5a69SCy Schubert * @return string or NULL on malloc failure (already logged). 877a39a5a69SCy Schubert */ 878a39a5a69SCy Schubert char* errinf_to_str_servfail(struct module_qstate* qstate); 879a39a5a69SCy Schubert 880a39a5a69SCy Schubert /** 881103ba509SCy Schubert * Create error info in string. For misc failures that are not servfail. 882103ba509SCy Schubert * @param qstate: query state. 883103ba509SCy Schubert * @return string or NULL on malloc failure (already logged). 884103ba509SCy Schubert */ 885103ba509SCy Schubert char* errinf_to_str_misc(struct module_qstate* qstate); 886103ba509SCy Schubert 887103ba509SCy Schubert /** 888bc892140SDag-Erling Smørgrav * Initialize the edns known options by allocating the required space. 889bc892140SDag-Erling Smørgrav * @param env: the module environment. 890bc892140SDag-Erling Smørgrav * @return false on failure (no memory). 891bc892140SDag-Erling Smørgrav */ 892bc892140SDag-Erling Smørgrav int edns_known_options_init(struct module_env* env); 893bc892140SDag-Erling Smørgrav 894bc892140SDag-Erling Smørgrav /** 895bc892140SDag-Erling Smørgrav * Free the allocated space for the known edns options. 896bc892140SDag-Erling Smørgrav * @param env: the module environment. 897bc892140SDag-Erling Smørgrav */ 898bc892140SDag-Erling Smørgrav void edns_known_options_delete(struct module_env* env); 899bc892140SDag-Erling Smørgrav 900bc892140SDag-Erling Smørgrav /** 901bc892140SDag-Erling Smørgrav * Register a known edns option. Overwrite the flags if it is already 902bc892140SDag-Erling Smørgrav * registered. Used before creating workers to register known edns options. 903bc892140SDag-Erling Smørgrav * @param opt_code: the edns option code. 904bc892140SDag-Erling Smørgrav * @param bypass_cache_stage: whether the option interacts with the cache. 905bc892140SDag-Erling Smørgrav * @param no_aggregation: whether the option implies more specific 906bc892140SDag-Erling Smørgrav * aggregation. 907bc892140SDag-Erling Smørgrav * @param env: the module environment. 908bc892140SDag-Erling Smørgrav * @return true on success, false on failure (registering more options than 909bc892140SDag-Erling Smørgrav * allowed or trying to register after the environment is copied to the 910bc892140SDag-Erling Smørgrav * threads.) 911bc892140SDag-Erling Smørgrav */ 912bc892140SDag-Erling Smørgrav int edns_register_option(uint16_t opt_code, int bypass_cache_stage, 913bc892140SDag-Erling Smørgrav int no_aggregation, struct module_env* env); 914bc892140SDag-Erling Smørgrav 915bc892140SDag-Erling Smørgrav /** 91665b390aaSDag-Erling Smørgrav * Register an inplace callback function. 917bc892140SDag-Erling Smørgrav * @param cb: pointer to the callback function. 91865b390aaSDag-Erling Smørgrav * @param type: inplace callback type. 91965b390aaSDag-Erling Smørgrav * @param cbarg: argument for the callback function, or NULL. 920bc892140SDag-Erling Smørgrav * @param env: the module environment. 92165b390aaSDag-Erling Smørgrav * @param id: module id. 922bc892140SDag-Erling Smørgrav * @return true on success, false on failure (out of memory or trying to 923bc892140SDag-Erling Smørgrav * register after the environment is copied to the threads.) 924bc892140SDag-Erling Smørgrav */ 92565b390aaSDag-Erling Smørgrav int 92665b390aaSDag-Erling Smørgrav inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg, 92765b390aaSDag-Erling Smørgrav struct module_env* env, int id); 928bc892140SDag-Erling Smørgrav 929bc892140SDag-Erling Smørgrav /** 93065b390aaSDag-Erling Smørgrav * Delete callback for specified type and module id. 931bc892140SDag-Erling Smørgrav * @param env: the module environment. 93265b390aaSDag-Erling Smørgrav * @param type: inplace callback type. 93365b390aaSDag-Erling Smørgrav * @param id: module id. 934bc892140SDag-Erling Smørgrav */ 93565b390aaSDag-Erling Smørgrav void 93665b390aaSDag-Erling Smørgrav inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type, 93765b390aaSDag-Erling Smørgrav int id); 938bc892140SDag-Erling Smørgrav 939bc892140SDag-Erling Smørgrav /** 940bc892140SDag-Erling Smørgrav * Delete all the inplace callback linked lists. 941bc892140SDag-Erling Smørgrav * @param env: the module environment. 942bc892140SDag-Erling Smørgrav */ 943bc892140SDag-Erling Smørgrav void inplace_cb_lists_delete(struct module_env* env); 944bc892140SDag-Erling Smørgrav 945bc892140SDag-Erling Smørgrav /** 946bc892140SDag-Erling Smørgrav * Check if an edns option is known. 947bc892140SDag-Erling Smørgrav * @param opt_code: the edns option code. 948bc892140SDag-Erling Smørgrav * @param env: the module environment. 949bc892140SDag-Erling Smørgrav * @return pointer to registered option if the edns option is known, 950bc892140SDag-Erling Smørgrav * NULL otherwise. 951bc892140SDag-Erling Smørgrav */ 952bc892140SDag-Erling Smørgrav struct edns_known_option* edns_option_is_known(uint16_t opt_code, 953bc892140SDag-Erling Smørgrav struct module_env* env); 954bc892140SDag-Erling Smørgrav 955bc892140SDag-Erling Smørgrav /** 956bc892140SDag-Erling Smørgrav * Check if an edns option needs to bypass the reply from cache stage. 957bc892140SDag-Erling Smørgrav * @param list: the edns options. 958bc892140SDag-Erling Smørgrav * @param env: the module environment. 959bc892140SDag-Erling Smørgrav * @return true if an edns option needs to bypass the cache stage, 960bc892140SDag-Erling Smørgrav * false otherwise. 961bc892140SDag-Erling Smørgrav */ 962bc892140SDag-Erling Smørgrav int edns_bypass_cache_stage(struct edns_option* list, 963bc892140SDag-Erling Smørgrav struct module_env* env); 964bc892140SDag-Erling Smørgrav 965bc892140SDag-Erling Smørgrav /** 96665b390aaSDag-Erling Smørgrav * Check if an unique mesh state is required. Might be triggered by EDNS option 96765b390aaSDag-Erling Smørgrav * or set for the complete env. 968bc892140SDag-Erling Smørgrav * @param list: the edns options. 969bc892140SDag-Erling Smørgrav * @param env: the module environment. 970bc892140SDag-Erling Smørgrav * @return true if an edns option needs a unique mesh state, 971bc892140SDag-Erling Smørgrav * false otherwise. 972bc892140SDag-Erling Smørgrav */ 97365b390aaSDag-Erling Smørgrav int unique_mesh_state(struct edns_option* list, struct module_env* env); 974bc892140SDag-Erling Smørgrav 975bc892140SDag-Erling Smørgrav /** 976bc892140SDag-Erling Smørgrav * Log the known edns options. 977bc892140SDag-Erling Smørgrav * @param level: the desired verbosity level. 978bc892140SDag-Erling Smørgrav * @param env: the module environment. 979bc892140SDag-Erling Smørgrav */ 980bc892140SDag-Erling Smørgrav void log_edns_known_options(enum verbosity_value level, 981bc892140SDag-Erling Smørgrav struct module_env* env); 982bc892140SDag-Erling Smørgrav 9834c75e3aaSDag-Erling Smørgrav /** 9844c75e3aaSDag-Erling Smørgrav * Copy state that may have happened in the subquery and is always relevant to 9854c75e3aaSDag-Erling Smørgrav * the super. 9864c75e3aaSDag-Erling Smørgrav * @param qstate: query state that finished. 9874c75e3aaSDag-Erling Smørgrav * @param id: module id. 9884c75e3aaSDag-Erling Smørgrav * @param super: the qstate to inform. 9894c75e3aaSDag-Erling Smørgrav */ 9904c75e3aaSDag-Erling Smørgrav void copy_state_to_super(struct module_qstate* qstate, int id, 9914c75e3aaSDag-Erling Smørgrav struct module_qstate* super); 9924c75e3aaSDag-Erling Smørgrav 993b7579f77SDag-Erling Smørgrav #endif /* UTIL_MODULE_H */ 994