1933707f3Ssthen /* 2933707f3Ssthen * util/module.h - DNS handling module interface 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen 36933707f3Ssthen /** 37933707f3Ssthen * \file 38933707f3Ssthen * 39933707f3Ssthen * This file contains the interface for DNS handling modules. 405d76a658Ssthen * 415d76a658Ssthen * The module interface uses the DNS modules as state machines. The 425d76a658Ssthen * state machines are activated in sequence to operate on queries. Once 435d76a658Ssthen * they are done, the reply is passed back. In the usual setup the mesh 445d76a658Ssthen * is the caller of the state machines and once things are done sends replies 455d76a658Ssthen * and invokes result callbacks. 465d76a658Ssthen * 475d76a658Ssthen * The module provides a number of functions, listed in the module_func_block. 485d76a658Ssthen * The module is inited and destroyed and memory usage queries, for the 495d76a658Ssthen * module as a whole, for entire-module state (such as a cache). And per-query 505d76a658Ssthen * functions are called, operate to move the state machine and cleanup of 515d76a658Ssthen * the per-query state. 525d76a658Ssthen * 535d76a658Ssthen * Most per-query state should simply be allocated in the query region. 545d76a658Ssthen * This is destroyed at the end of the query. 555d76a658Ssthen * 565d76a658Ssthen * The module environment contains services and information and caches 575d76a658Ssthen * shared by the modules and the rest of the system. It also contains 585d76a658Ssthen * function pointers for module-specific tasks (like sending queries). 595d76a658Ssthen * 605d76a658Ssthen * *** Example module calls for a normal query 615d76a658Ssthen * 625d76a658Ssthen * In this example, the query does not need recursion, all the other data 635d76a658Ssthen * can be found in the cache. This makes the example shorter. 645d76a658Ssthen * 655d76a658Ssthen * At the start of the program the iterator module is initialised. 665d76a658Ssthen * The iterator module sets up its global state, such as donotquery lists 675d76a658Ssthen * and private address trees. 685d76a658Ssthen * 695d76a658Ssthen * A query comes in, and a mesh entry is created for it. The mesh 705d76a658Ssthen * starts the resolution process. The validator module is the first 715d76a658Ssthen * in the list of modules, and it is started on this new query. The 725d76a658Ssthen * operate() function is called. The validator decides it needs not do 735d76a658Ssthen * anything yet until there is a result and returns wait_module, that 745d76a658Ssthen * causes the next module in the list to be started. 755d76a658Ssthen * 765d76a658Ssthen * The next module is the iterator. It is started on the passed query and 775d76a658Ssthen * decides to perform a lookup. For this simple example, the delegation 785d76a658Ssthen * point information is available, and all the iterator wants to do is 795d76a658Ssthen * send a UDP query. The iterator uses env.send_query() to send the 805d76a658Ssthen * query. Then the iterator suspends (returns from the operate call). 815d76a658Ssthen * 825d76a658Ssthen * When the UDP reply comes back (and on errors and timeouts), the 835d76a658Ssthen * operate function is called for the query, on the iterator module, 845d76a658Ssthen * with the event that there is a reply. The iterator decides that this 855d76a658Ssthen * is enough, the work is done. It returns the value finished from the 865d76a658Ssthen * operate call, which causes the previous module to be started. 875d76a658Ssthen * 885d76a658Ssthen * The previous module, the validator module, is started with the event 895d76a658Ssthen * that the iterator module is done. The validator decides to validate 905d76a658Ssthen * the query. Once it is done (which could take recursive lookups, but 915d76a658Ssthen * in this example no recursive lookups are needed), it returns from the 925d76a658Ssthen * operate function with finished. 935d76a658Ssthen * 945d76a658Ssthen * There is no previous module from the validator module, and the mesh 955d76a658Ssthen * takes this to mean that the query is finally done. The mesh invokes 965d76a658Ssthen * callbacks and sends packets to queriers. 975d76a658Ssthen * 985d76a658Ssthen * If other modules had been waiting (recursively) on the answer to this 995d76a658Ssthen * query, then the mesh will tell them about it. It calls the inform_super 1005d76a658Ssthen * routine on all the waiting modules, and once that is done it calls all of 1015d76a658Ssthen * them with the operate() call. During inform_super the query that is done 1025d76a658Ssthen * still exists and information can be copied from it (but the module should 1035d76a658Ssthen * not really re-entry codepoints and services). During the operate call 1045d76a658Ssthen * the modules can use stored state to continue operation with the results. 1055d76a658Ssthen * (network buffers are used to contain the answer packet during the 1065d76a658Ssthen * inform_super phase, but after that the network buffers will be cleared 1075d76a658Ssthen * of their contents so that other tasks can be performed). 1085d76a658Ssthen * 1095d76a658Ssthen * *** Example module calls for recursion 1105d76a658Ssthen * 1115d76a658Ssthen * A module is called in operate, and it decides that it wants to perform 1125d76a658Ssthen * recursion. That is, it wants the full state-machine-list to operate on 1135d76a658Ssthen * a different query. It calls env.attach_sub() to create a new query state. 1145d76a658Ssthen * The routine returns the newly created state, and potentially the module 1155d76a658Ssthen * can edit the module-states for the newly created query (i.e. pass along 1165d76a658Ssthen * some information, like delegation points). The module then suspends, 1175d76a658Ssthen * returns from the operate routine. 1185d76a658Ssthen * 1195d76a658Ssthen * The mesh meanwhile will have the newly created query (or queries) on 1205d76a658Ssthen * a waiting list, and will call operate() on this query (or queries). 1215d76a658Ssthen * It starts again at the start of the module list for them. The query 1225d76a658Ssthen * (or queries) continue to operate their state machines, until they are 1235d76a658Ssthen * done. When they are done the mesh calls inform_super on the module that 1245d76a658Ssthen * wanted the recursion. After that the mesh calls operate() on the module 1255d76a658Ssthen * that wanted to do the recursion, and during this phase the module could, 1265d76a658Ssthen * for example, decide to create more recursions. 1275d76a658Ssthen * 1285d76a658Ssthen * If the module decides it no longer wants the recursive information 1295d76a658Ssthen * it can call detach_subs. Those queries will still run to completion, 1305d76a658Ssthen * potentially filling the cache with information. Inform_super is not 1315d76a658Ssthen * called any more. 1325d76a658Ssthen * 1335d76a658Ssthen * The iterator module will fetch items from the cache, so a recursion 1345d76a658Ssthen * attempt may complete very quickly if the item is in cache. The calling 1355d76a658Ssthen * module has to wait for completion or eventual timeout. A recursive query 1365d76a658Ssthen * that times out returns a servfail rcode (servfail is also returned for 1375d76a658Ssthen * other errors during the lookup). 1385d76a658Ssthen * 1395d76a658Ssthen * Results are passed in the qstate, the rcode member is used to pass 1405d76a658Ssthen * errors without requiring memory allocation, so that the code can continue 1415d76a658Ssthen * in out-of-memory conditions. If the rcode member is 0 (NOERROR) then 1425d76a658Ssthen * the dns_msg entry contains a filled out message. This message may 1435d76a658Ssthen * also contain an rcode that is nonzero, but in this case additional 1445d76a658Ssthen * information (query, additional) can be passed along. 1455d76a658Ssthen * 146*98bc733bSsthen * The rcode and dns_msg are used to pass the result from the rightmost 1475d76a658Ssthen * module towards the leftmost modules and then towards the user. 1485d76a658Ssthen * 1495d76a658Ssthen * If you want to avoid recursion-cycles where queries need other queries 1505d76a658Ssthen * that need the first one, use detect_cycle() to see if that will happen. 1515d76a658Ssthen * 152933707f3Ssthen */ 153933707f3Ssthen 154933707f3Ssthen #ifndef UTIL_MODULE_H 155933707f3Ssthen #define UTIL_MODULE_H 156933707f3Ssthen #include "util/storage/lruhash.h" 157933707f3Ssthen #include "util/data/msgreply.h" 158933707f3Ssthen #include "util/data/msgparse.h" 1595d76a658Ssthen struct sldns_buffer; 160933707f3Ssthen struct alloc_cache; 161933707f3Ssthen struct rrset_cache; 162933707f3Ssthen struct key_cache; 163933707f3Ssthen struct config_file; 164933707f3Ssthen struct slabhash; 165933707f3Ssthen struct query_info; 166933707f3Ssthen struct edns_data; 167933707f3Ssthen struct regional; 168933707f3Ssthen struct worker; 169bdfc4d55Sflorian struct comm_base; 170bdfc4d55Sflorian struct auth_zones; 171bdfc4d55Sflorian struct outside_network; 172933707f3Ssthen struct module_qstate; 173933707f3Ssthen struct ub_randstate; 174933707f3Ssthen struct mesh_area; 175933707f3Ssthen struct mesh_state; 176933707f3Ssthen struct val_anchors; 177933707f3Ssthen struct val_neg_cache; 178933707f3Ssthen struct iter_forwards; 179d8d14d0cSsthen struct iter_hints; 1802be9e038Ssthen struct respip_set; 1812be9e038Ssthen struct respip_client_info; 1822be9e038Ssthen struct respip_addr_info; 1832bdc0ed1Ssthen struct module_stack; 184933707f3Ssthen 185933707f3Ssthen /** Maximum number of modules in operation */ 18677079be7Ssthen #define MAX_MODULE 16 18777079be7Ssthen 18877079be7Ssthen /** Maximum number of known edns options */ 18977079be7Ssthen #define MAX_KNOWN_EDNS_OPTS 256 19077079be7Ssthen 1910bdb4f62Ssthen struct errinf_strlist { 1920bdb4f62Ssthen /** next item in list */ 1930bdb4f62Ssthen struct errinf_strlist* next; 1940bdb4f62Ssthen /** config option string */ 1950bdb4f62Ssthen char* str; 1960bdb4f62Ssthen /** EDE code companion to the error str */ 1970bdb4f62Ssthen int reason_bogus; 1980bdb4f62Ssthen }; 1990bdb4f62Ssthen 20077079be7Ssthen enum inplace_cb_list_type { 20177079be7Ssthen /* Inplace callbacks for when a resolved reply is ready to be sent to the 20277079be7Ssthen * front.*/ 20377079be7Ssthen inplace_cb_reply = 0, 20477079be7Ssthen /* Inplace callbacks for when a reply is given from the cache. */ 20577079be7Ssthen inplace_cb_reply_cache, 20677079be7Ssthen /* Inplace callbacks for when a reply is given with local data 20777079be7Ssthen * (or Chaos reply). */ 20877079be7Ssthen inplace_cb_reply_local, 20977079be7Ssthen /* Inplace callbacks for when the reply is servfail. */ 21077079be7Ssthen inplace_cb_reply_servfail, 21177079be7Ssthen /* Inplace callbacks for when a query is ready to be sent to the back.*/ 21277079be7Ssthen inplace_cb_query, 2132be9e038Ssthen /* Inplace callback for when a reply is received from the back. */ 2142be9e038Ssthen inplace_cb_query_response, 2152be9e038Ssthen /* Inplace callback for when EDNS is parsed on a reply received from the 2162be9e038Ssthen * back. */ 2172be9e038Ssthen inplace_cb_edns_back_parsed, 21877079be7Ssthen /* Total number of types. Used for array initialization. 21977079be7Ssthen * Should always be last. */ 22077079be7Ssthen inplace_cb_types_total 22177079be7Ssthen }; 22277079be7Ssthen 22377079be7Ssthen 22477079be7Ssthen /** Known edns option. Can be populated during modules' init. */ 22577079be7Ssthen struct edns_known_option { 22677079be7Ssthen /** type of this edns option */ 22777079be7Ssthen uint16_t opt_code; 22877079be7Ssthen /** whether the option needs to bypass the cache stage */ 22977079be7Ssthen int bypass_cache_stage; 23077079be7Ssthen /** whether the option needs mesh aggregation */ 23177079be7Ssthen int no_aggregation; 23277079be7Ssthen }; 23377079be7Ssthen 23477079be7Ssthen /** 2352be9e038Ssthen * Inplace callback list of registered routines to be called. 2362be9e038Ssthen */ 2372be9e038Ssthen struct inplace_cb { 2382be9e038Ssthen /** next in list */ 2392be9e038Ssthen struct inplace_cb* next; 2402be9e038Ssthen /** Inplace callback routine */ 2412be9e038Ssthen void* cb; 2422be9e038Ssthen void* cb_arg; 2432be9e038Ssthen /** module id */ 2442be9e038Ssthen int id; 2452be9e038Ssthen }; 2462be9e038Ssthen 2472be9e038Ssthen /** 24877079be7Ssthen * Inplace callback function called before replying. 2492308e98cSsthen * Called as func(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, 2502308e98cSsthen * region, id, python_callback) 25177079be7Ssthen * Where: 25277079be7Ssthen * qinfo: the query info. 25377079be7Ssthen * qstate: the module state. NULL when calling before the query reaches the 25477079be7Ssthen * mesh states. 25577079be7Ssthen * rep: reply_info. Could be NULL. 25677079be7Ssthen * rcode: the return code. 25777079be7Ssthen * edns: the edns_data of the reply. When qstate is NULL, it is also used as 25877079be7Ssthen * the edns input. 25977079be7Ssthen * opt_list_out: the edns options list for the reply. 2602308e98cSsthen * repinfo: reply information for a communication point. NULL when calling 2612308e98cSsthen * during the mesh states; the same could be found from 2622308e98cSsthen * qstate->mesh_info->reply_list. 26377079be7Ssthen * region: region to store data. 2642308e98cSsthen * id: module id. 26577079be7Ssthen * python_callback: only used for registering a python callback function. 26677079be7Ssthen */ 26777079be7Ssthen typedef int inplace_cb_reply_func_type(struct query_info* qinfo, 26877079be7Ssthen struct module_qstate* qstate, struct reply_info* rep, int rcode, 26977079be7Ssthen struct edns_data* edns, struct edns_option** opt_list_out, 2709982a05dSsthen struct comm_reply* repinfo, struct regional* region, 2719982a05dSsthen struct timeval* start_time, int id, void* callback); 27277079be7Ssthen 27377079be7Ssthen /** 27477079be7Ssthen * Inplace callback function called before sending the query to a nameserver. 27577079be7Ssthen * Called as func(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, 2762308e98cSsthen * id, python_callback) 27777079be7Ssthen * Where: 27877079be7Ssthen * qinfo: query info. 27977079be7Ssthen * flags: flags of the query. 28077079be7Ssthen * qstate: query state. 28177079be7Ssthen * addr: to which server to send the query. 28277079be7Ssthen * addrlen: length of addr. 28377079be7Ssthen * zone: name of the zone of the delegation point. wireformat dname. 28477079be7Ssthen * This is the delegation point name for which the server is deemed 28577079be7Ssthen * authoritative. 28677079be7Ssthen * zonelen: length of zone. 28777079be7Ssthen * region: region to store data. 2882308e98cSsthen * id: module id. 28977079be7Ssthen * python_callback: only used for registering a python callback function. 29077079be7Ssthen */ 29177079be7Ssthen typedef int inplace_cb_query_func_type(struct query_info* qinfo, uint16_t flags, 29277079be7Ssthen struct module_qstate* qstate, struct sockaddr_storage* addr, 29377079be7Ssthen socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region, 2942be9e038Ssthen int id, void* callback); 29577079be7Ssthen 29677079be7Ssthen /** 2972be9e038Ssthen * Inplace callback function called after parsing edns on query reply. 2982308e98cSsthen * Called as func(qstate, id, cb_args) 2992be9e038Ssthen * Where: 3002308e98cSsthen * qstate: the query state. 3012308e98cSsthen * id: module id. 3022be9e038Ssthen * cb_args: argument passed when registering callback. 30377079be7Ssthen */ 3042be9e038Ssthen typedef int inplace_cb_edns_back_parsed_func_type(struct module_qstate* qstate, 3052be9e038Ssthen int id, void* cb_args); 3062be9e038Ssthen 30777079be7Ssthen /** 3082be9e038Ssthen * Inplace callback function called after parsing query response. 3092308e98cSsthen * Called as func(qstate, response, id, cb_args) 3102be9e038Ssthen * Where: 3112308e98cSsthen * qstate: the query state. 3122308e98cSsthen * response: query response. 3132308e98cSsthen * id: module id. 3142be9e038Ssthen * cb_args: argument passed when registering callback. 31577079be7Ssthen */ 3162be9e038Ssthen typedef int inplace_cb_query_response_func_type(struct module_qstate* qstate, 3172be9e038Ssthen struct dns_msg* response, int id, void* cb_args); 318933707f3Ssthen 319933707f3Ssthen /** 320eaf2578eSsthen * Function called when looking for (expired) cached answers during the serve 321eaf2578eSsthen * expired logic. 322eaf2578eSsthen * Called as func(qstate, lookup_qinfo) 323eaf2578eSsthen * Where: 324eaf2578eSsthen * qstate: the query state. 325eaf2578eSsthen * lookup_qinfo: the qinfo to lookup for. 326eaf2578eSsthen */ 327eaf2578eSsthen typedef struct dns_msg* serve_expired_lookup_func_type( 328eaf2578eSsthen struct module_qstate* qstate, struct query_info* lookup_qinfo); 329eaf2578eSsthen 330eaf2578eSsthen /** 331933707f3Ssthen * Module environment. 332933707f3Ssthen * Services and data provided to the module. 333933707f3Ssthen */ 334933707f3Ssthen struct module_env { 335933707f3Ssthen /* --- data --- */ 336933707f3Ssthen /** config file with config options */ 337933707f3Ssthen struct config_file* cfg; 338933707f3Ssthen /** shared message cache */ 339933707f3Ssthen struct slabhash* msg_cache; 340933707f3Ssthen /** shared rrset cache */ 341933707f3Ssthen struct rrset_cache* rrset_cache; 342933707f3Ssthen /** shared infrastructure cache (edns, lameness) */ 343933707f3Ssthen struct infra_cache* infra_cache; 344933707f3Ssthen /** shared key cache */ 345933707f3Ssthen struct key_cache* key_cache; 346933707f3Ssthen 347933707f3Ssthen /* --- services --- */ 348933707f3Ssthen /** 349933707f3Ssthen * Send serviced DNS query to server. UDP/TCP and EDNS is handled. 350933707f3Ssthen * operate() should return with wait_reply. Later on a callback 351933707f3Ssthen * will cause operate() to be called with event timeout or reply. 352933707f3Ssthen * The time until a timeout is calculated from roundtrip timing, 353933707f3Ssthen * several UDP retries are attempted. 35477079be7Ssthen * @param qinfo: query info. 355933707f3Ssthen * @param flags: host order flags word, with opcode and CD bit. 356933707f3Ssthen * @param dnssec: if set, EDNS record will have bits set. 357933707f3Ssthen * If EDNS_DO bit is set, DO bit is set in EDNS records. 358933707f3Ssthen * If BIT_CD is set, CD bit is set in queries with EDNS records. 359933707f3Ssthen * @param want_dnssec: if set, the validator wants DNSSEC. Without 360933707f3Ssthen * EDNS, the answer is likely to be useless for this domain. 36198f3ca02Sbrad * @param nocaps: do not use caps_for_id, use the qname as given. 36298f3ca02Sbrad * (ignored if caps_for_id is disabled). 363e21c60efSsthen * @param check_ratelimit: if set, will check ratelimit before sending out. 364933707f3Ssthen * @param addr: where to. 365933707f3Ssthen * @param addrlen: length of addr. 366933707f3Ssthen * @param zone: delegation point name. 367933707f3Ssthen * @param zonelen: length of zone name. 368e21c60efSsthen * @param tcp_upstream: use TCP for upstream queries. 36977079be7Ssthen * @param ssl_upstream: use SSL for upstream queries. 37020237c55Ssthen * @param tls_auth_name: if ssl_upstream, use this name with TLS 37120237c55Ssthen * authentication. 372e21c60efSsthen * @param q: which query state to reactivate upon return. 373e21c60efSsthen * @param was_ratelimited: it will signal back if the query failed to pass the 374e21c60efSsthen * ratelimit check. 375933707f3Ssthen * @return: false on failure (memory or socket related). no query was 376933707f3Ssthen * sent. Or returns an outbound entry with qsent and qstate set. 377933707f3Ssthen * This outbound_entry will be used on later module invocations 378933707f3Ssthen * that involve this query (timeout, error or reply). 379933707f3Ssthen */ 38077079be7Ssthen struct outbound_entry* (*send_query)(struct query_info* qinfo, 38177079be7Ssthen uint16_t flags, int dnssec, int want_dnssec, int nocaps, 382e21c60efSsthen int check_ratelimit, 3832ee382b6Ssthen struct sockaddr_storage* addr, socklen_t addrlen, 384e21c60efSsthen uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, 385e21c60efSsthen char* tls_auth_name, struct module_qstate* q, int* was_ratelimited); 386933707f3Ssthen 387933707f3Ssthen /** 388933707f3Ssthen * Detach-subqueries. 389933707f3Ssthen * Remove all sub-query references from this query state. 390933707f3Ssthen * Keeps super-references of those sub-queries correct. 391933707f3Ssthen * Updates stat items in mesh_area structure. 392933707f3Ssthen * @param qstate: used to find mesh state. 393933707f3Ssthen */ 394933707f3Ssthen void (*detach_subs)(struct module_qstate* qstate); 395933707f3Ssthen 396933707f3Ssthen /** 397933707f3Ssthen * Attach subquery. 398933707f3Ssthen * Creates it if it does not exist already. 399933707f3Ssthen * Keeps sub and super references correct. 400933707f3Ssthen * Updates stat items in mesh_area structure. 401933707f3Ssthen * Pass if it is priming query or not. 402933707f3Ssthen * return: 403933707f3Ssthen * o if error (malloc) happened. 404933707f3Ssthen * o need to initialise the new state (module init; it is a new state). 405933707f3Ssthen * so that the next run of the query with this module is successful. 406933707f3Ssthen * o no init needed, attachment successful. 407933707f3Ssthen * 408933707f3Ssthen * @param qstate: the state to find mesh state, and that wants to 409933707f3Ssthen * receive the results from the new subquery. 410933707f3Ssthen * @param qinfo: what to query for (copied). 411933707f3Ssthen * @param qflags: what flags to use (RD, CD flag or not). 412933707f3Ssthen * @param prime: if it is a (stub) priming query. 41357dceb2aSbrad * @param valrec: validation lookup recursion, does not need validation 414933707f3Ssthen * @param newq: If the new subquery needs initialisation, it is 415933707f3Ssthen * returned, otherwise NULL is returned. 416933707f3Ssthen * @return: false on error, true if success (and init may be needed). 417933707f3Ssthen */ 418933707f3Ssthen int (*attach_sub)(struct module_qstate* qstate, 419933707f3Ssthen struct query_info* qinfo, uint16_t qflags, int prime, 42057dceb2aSbrad int valrec, struct module_qstate** newq); 421933707f3Ssthen 422933707f3Ssthen /** 4232be9e038Ssthen * Add detached query. 4242be9e038Ssthen * Creates it if it does not exist already. 4252be9e038Ssthen * Does not make super/sub references. 4262be9e038Ssthen * Performs a cycle detection - for double check - and fails if there is 4272be9e038Ssthen * one. 4282be9e038Ssthen * Updates stat items in mesh_area structure. 4292be9e038Ssthen * Pass if it is priming query or not. 4302be9e038Ssthen * return: 4312be9e038Ssthen * o if error (malloc) happened. 4322be9e038Ssthen * o need to initialise the new state (module init; it is a new state). 4332be9e038Ssthen * so that the next run of the query with this module is successful. 4342be9e038Ssthen * o no init needed, attachment successful. 4352be9e038Ssthen * o added subquery, created if it did not exist already. 4362be9e038Ssthen * 4372be9e038Ssthen * @param qstate: the state to find mesh state, and that wants to receive 4382be9e038Ssthen * the results from the new subquery. 4392be9e038Ssthen * @param qinfo: what to query for (copied). 4402be9e038Ssthen * @param qflags: what flags to use (RD / CD flag or not). 4412be9e038Ssthen * @param prime: if it is a (stub) priming query. 4422be9e038Ssthen * @param valrec: if it is a validation recursion query (lookup of key, DS). 4432be9e038Ssthen * @param newq: If the new subquery needs initialisation, it is returned, 4442be9e038Ssthen * otherwise NULL is returned. 4452be9e038Ssthen * @param sub: The added mesh state, created if it did not exist already. 4462be9e038Ssthen * @return: false on error, true if success (and init may be needed). 4472be9e038Ssthen */ 4482be9e038Ssthen int (*add_sub)(struct module_qstate* qstate, 4492be9e038Ssthen struct query_info* qinfo, uint16_t qflags, int prime, 4502be9e038Ssthen int valrec, struct module_qstate** newq, 4512be9e038Ssthen struct mesh_state** sub); 4522be9e038Ssthen 4532be9e038Ssthen /** 454933707f3Ssthen * Kill newly attached sub. If attach_sub returns newq for 455933707f3Ssthen * initialisation, but that fails, then this routine will cleanup and 456bdfc4d55Sflorian * delete the freshly created sub. 457933707f3Ssthen * @param newq: the new subquery that is no longer needed. 458933707f3Ssthen * It is removed. 459933707f3Ssthen */ 460933707f3Ssthen void (*kill_sub)(struct module_qstate* newq); 461933707f3Ssthen 462933707f3Ssthen /** 463933707f3Ssthen * Detect if adding a dependency for qstate on name,type,class will 464933707f3Ssthen * create a dependency cycle. 465933707f3Ssthen * @param qstate: given mesh querystate. 466933707f3Ssthen * @param qinfo: query info for dependency. 467933707f3Ssthen * @param flags: query flags of dependency, RD/CD flags. 468933707f3Ssthen * @param prime: if dependency is a priming query or not. 46957dceb2aSbrad * @param valrec: validation lookup recursion, does not need validation 470933707f3Ssthen * @return true if the name,type,class exists and the given 471933707f3Ssthen * qstate mesh exists as a dependency of that name. Thus 472933707f3Ssthen * if qstate becomes dependent on name,type,class then a 473933707f3Ssthen * cycle is created. 474933707f3Ssthen */ 475933707f3Ssthen int (*detect_cycle)(struct module_qstate* qstate, 47657dceb2aSbrad struct query_info* qinfo, uint16_t flags, int prime, 47757dceb2aSbrad int valrec); 478933707f3Ssthen 479933707f3Ssthen /** region for temporary usage. May be cleared after operate() call. */ 480933707f3Ssthen struct regional* scratch; 481933707f3Ssthen /** buffer for temporary usage. May be cleared after operate() call. */ 4825d76a658Ssthen struct sldns_buffer* scratch_buffer; 483933707f3Ssthen /** internal data for daemon - worker thread. */ 484933707f3Ssthen struct worker* worker; 485bdfc4d55Sflorian /** the worker event base */ 486bdfc4d55Sflorian struct comm_base* worker_base; 487bdfc4d55Sflorian /** the outside network */ 488bdfc4d55Sflorian struct outside_network* outnet; 489933707f3Ssthen /** mesh area with query state dependencies */ 490933707f3Ssthen struct mesh_area* mesh; 491933707f3Ssthen /** allocation service */ 492933707f3Ssthen struct alloc_cache* alloc; 493933707f3Ssthen /** random table to generate random numbers */ 494933707f3Ssthen struct ub_randstate* rnd; 495933707f3Ssthen /** time in seconds, converted to integer */ 496229e174cSsthen time_t* now; 497933707f3Ssthen /** time in microseconds. Relatively recent. */ 498933707f3Ssthen struct timeval* now_tv; 499933707f3Ssthen /** is validation required for messages, controls client-facing 500933707f3Ssthen * validation status (AD bits) and servfails */ 501933707f3Ssthen int need_to_validate; 502933707f3Ssthen /** trusted key storage; these are the configured keys, if not NULL, 503933707f3Ssthen * otherwise configured by validator. These are the trust anchors, 504933707f3Ssthen * and are not primed and ready for validation, but on the bright 505933707f3Ssthen * side, they are read only memory, thus no locks and fast. */ 506933707f3Ssthen struct val_anchors* anchors; 507933707f3Ssthen /** negative cache, configured by the validator. if not NULL, 508933707f3Ssthen * contains NSEC record lookup trees. */ 509933707f3Ssthen struct val_neg_cache* neg_cache; 510933707f3Ssthen /** the 5011-probe timer (if any) */ 511933707f3Ssthen struct comm_timer* probe_timer; 512bdfc4d55Sflorian /** auth zones */ 513bdfc4d55Sflorian struct auth_zones* auth_zones; 514933707f3Ssthen /** Mapping of forwarding zones to targets. 5152bdc0ed1Ssthen * iterator forwarder information. */ 516933707f3Ssthen struct iter_forwards* fwds; 517d8d14d0cSsthen /** 5182bdc0ed1Ssthen * iterator stub information. 519d8d14d0cSsthen * The hints -- these aren't stored in the cache because they don't 520d8d14d0cSsthen * expire. The hints are always used to "prime" the cache. Note 521d8d14d0cSsthen * that both root hints and stub zone "hints" are stored in this 522d8d14d0cSsthen * data structure. 523d8d14d0cSsthen */ 524d8d14d0cSsthen struct iter_hints* hints; 525933707f3Ssthen /** module specific data. indexed by module id. */ 526933707f3Ssthen void* modinfo[MAX_MODULE]; 52777079be7Ssthen 52877079be7Ssthen /* Shared linked list of inplace callback functions */ 5292be9e038Ssthen struct inplace_cb* inplace_cb_lists[inplace_cb_types_total]; 53077079be7Ssthen 53177079be7Ssthen /** 53277079be7Ssthen * Shared array of known edns options (size MAX_KNOWN_EDNS_OPTS). 53377079be7Ssthen * Filled by edns literate modules during init. 53477079be7Ssthen */ 53577079be7Ssthen struct edns_known_option* edns_known_options; 53677079be7Ssthen /* Number of known edns options */ 53777079be7Ssthen size_t edns_known_options_num; 538eba819a2Ssthen /** EDNS client string information */ 539eba819a2Ssthen struct edns_strings* edns_strings; 5402be9e038Ssthen 5412bdc0ed1Ssthen /** module stack */ 5422bdc0ed1Ssthen struct module_stack* modstack; 5432bdc0ed1Ssthen #ifdef USE_CACHEDB 5442bdc0ed1Ssthen /** the cachedb enabled value, copied and stored here. */ 5452bdc0ed1Ssthen int cachedb_enabled; 5462bdc0ed1Ssthen #endif 5472be9e038Ssthen /* Make every mesh state unique, do not aggregate mesh states. */ 5482be9e038Ssthen int unique_mesh; 549933707f3Ssthen }; 550933707f3Ssthen 551933707f3Ssthen /** 552933707f3Ssthen * External visible states of the module state machine 553933707f3Ssthen * Modules may also have an internal state. 554933707f3Ssthen * Modules are supposed to run to completion or until blocked. 555933707f3Ssthen */ 556933707f3Ssthen enum module_ext_state { 557933707f3Ssthen /** initial state - new query */ 558933707f3Ssthen module_state_initial = 0, 559933707f3Ssthen /** waiting for reply to outgoing network query */ 560933707f3Ssthen module_wait_reply, 561933707f3Ssthen /** module is waiting for another module */ 562933707f3Ssthen module_wait_module, 563933707f3Ssthen /** module is waiting for another module; that other is restarted */ 564933707f3Ssthen module_restart_next, 565933707f3Ssthen /** module is waiting for sub-query */ 566933707f3Ssthen module_wait_subquery, 567933707f3Ssthen /** module could not finish the query */ 568933707f3Ssthen module_error, 569933707f3Ssthen /** module is finished with query */ 570933707f3Ssthen module_finished 571933707f3Ssthen }; 572933707f3Ssthen 573933707f3Ssthen /** 574933707f3Ssthen * Events that happen to modules, that start or wakeup modules. 575933707f3Ssthen */ 576933707f3Ssthen enum module_ev { 577933707f3Ssthen /** new query */ 578933707f3Ssthen module_event_new = 0, 579933707f3Ssthen /** query passed by other module */ 580933707f3Ssthen module_event_pass, 581933707f3Ssthen /** reply inbound from server */ 582933707f3Ssthen module_event_reply, 583933707f3Ssthen /** no reply, timeout or other error */ 584933707f3Ssthen module_event_noreply, 585933707f3Ssthen /** reply is there, but capitalisation check failed */ 586933707f3Ssthen module_event_capsfail, 587933707f3Ssthen /** next module is done, and its reply is awaiting you */ 588933707f3Ssthen module_event_moddone, 589933707f3Ssthen /** error */ 590933707f3Ssthen module_event_error 591933707f3Ssthen }; 592933707f3Ssthen 593933707f3Ssthen /** 594933707f3Ssthen * Linked list of sockaddrs 595933707f3Ssthen * May be allocated such that only 'len' bytes of addr exist for the structure. 596933707f3Ssthen */ 597933707f3Ssthen struct sock_list { 598933707f3Ssthen /** next in list */ 599933707f3Ssthen struct sock_list* next; 600933707f3Ssthen /** length of addr */ 601933707f3Ssthen socklen_t len; 602933707f3Ssthen /** sockaddr */ 603933707f3Ssthen struct sockaddr_storage addr; 604933707f3Ssthen }; 605933707f3Ssthen 6062be9e038Ssthen struct respip_action_info; 6072be9e038Ssthen 608933707f3Ssthen /** 609eaf2578eSsthen * Struct to hold relevant data for serve expired 610eaf2578eSsthen */ 611eaf2578eSsthen struct serve_expired_data { 612eaf2578eSsthen struct comm_timer* timer; 613eaf2578eSsthen serve_expired_lookup_func_type* get_cached_answer; 614eaf2578eSsthen }; 615eaf2578eSsthen 616eaf2578eSsthen /** 617933707f3Ssthen * Module state, per query. 618933707f3Ssthen */ 619933707f3Ssthen struct module_qstate { 620933707f3Ssthen /** which query is being answered: name, type, class */ 621933707f3Ssthen struct query_info qinfo; 622933707f3Ssthen /** flags uint16 from query */ 623933707f3Ssthen uint16_t query_flags; 624933707f3Ssthen /** if this is a (stub or root) priming query (with hints) */ 625933707f3Ssthen int is_priming; 62657dceb2aSbrad /** if this is a validation recursion query that does not get 62757dceb2aSbrad * validation itself */ 62857dceb2aSbrad int is_valrec; 6298b7325afSsthen #ifdef CLIENT_SUBNET 6308b7325afSsthen /** the client network address is needed for the client-subnet option 6318b7325afSsthen * when prefetching, but we can't use reply_list in mesh_info, because 6328b7325afSsthen * we don't want to send a reply for the internal query. */ 6338b7325afSsthen struct sockaddr_storage client_addr; 6348b7325afSsthen #endif 635933707f3Ssthen 636933707f3Ssthen /** comm_reply contains server replies */ 637933707f3Ssthen struct comm_reply* reply; 638933707f3Ssthen /** the reply message, with message for client and calling module */ 639933707f3Ssthen struct dns_msg* return_msg; 640933707f3Ssthen /** the rcode, in case of error, instead of a reply message */ 641933707f3Ssthen int return_rcode; 642933707f3Ssthen /** origin of the reply (can be NULL from cache, list for cnames) */ 643933707f3Ssthen struct sock_list* reply_origin; 644933707f3Ssthen /** IP blacklist for queries */ 645933707f3Ssthen struct sock_list* blacklist; 646933707f3Ssthen /** region for this query. Cleared when query process finishes. */ 647933707f3Ssthen struct regional* region; 648933707f3Ssthen /** failure reason information if val-log-level is high */ 6490bdb4f62Ssthen struct errinf_strlist* errinf; 650933707f3Ssthen /** which module is executing */ 651933707f3Ssthen int curmod; 652933707f3Ssthen /** module states */ 653933707f3Ssthen enum module_ext_state ext_state[MAX_MODULE]; 654933707f3Ssthen /** module specific data for query. indexed by module id. */ 655933707f3Ssthen void* minfo[MAX_MODULE]; 656933707f3Ssthen /** environment for this query */ 657933707f3Ssthen struct module_env* env; 658933707f3Ssthen /** mesh related information for this query */ 659933707f3Ssthen struct mesh_state* mesh_info; 660933707f3Ssthen /** how many seconds before expiry is this prefetched (0 if not) */ 661229e174cSsthen time_t prefetch_leeway; 662eaf2578eSsthen /** serve expired data */ 663eaf2578eSsthen struct serve_expired_data* serve_expired_data; 66477079be7Ssthen 66577079be7Ssthen /** incoming edns options from the front end */ 66677079be7Ssthen struct edns_option* edns_opts_front_in; 66777079be7Ssthen /** outgoing edns options to the back end */ 66877079be7Ssthen struct edns_option* edns_opts_back_out; 66977079be7Ssthen /** incoming edns options from the back end */ 67077079be7Ssthen struct edns_option* edns_opts_back_in; 67177079be7Ssthen /** outgoing edns options to the front end */ 67277079be7Ssthen struct edns_option* edns_opts_front_out; 67377079be7Ssthen /** whether modules should answer from the cache */ 67477079be7Ssthen int no_cache_lookup; 67577079be7Ssthen /** whether modules should store answer in the cache */ 67677079be7Ssthen int no_cache_store; 677bdfc4d55Sflorian /** whether to refetch a fresh answer on finishing this state*/ 678bdfc4d55Sflorian int need_refetch; 6792308e98cSsthen /** whether the query (or a subquery) was ratelimited */ 6802308e98cSsthen int was_ratelimited; 681d1e2768aSsthen /** time when query was started. This is when the qstate is created. 682d1e2768aSsthen * This is used so that type NS data cannot be overwritten by them 683d1e2768aSsthen * expiring while the lookup is in progress, using data fetched from 684d1e2768aSsthen * those servers. By comparing expiry time with qstarttime for type NS. 685d1e2768aSsthen */ 686d1e2768aSsthen time_t qstarttime; 6878b7325afSsthen /** whether a message from cachedb will be used for the reply */ 6888b7325afSsthen int is_cachedb_answer; 6892be9e038Ssthen 6902be9e038Ssthen /** 6912be9e038Ssthen * Attributes of clients that share the qstate that may affect IP-based 6922be9e038Ssthen * actions. 6932be9e038Ssthen */ 6942be9e038Ssthen struct respip_client_info* client_info; 6952be9e038Ssthen 6962be9e038Ssthen /** Extended result of response-ip action processing, mainly 6972be9e038Ssthen * for logging purposes. */ 6982be9e038Ssthen struct respip_action_info* respip_action_info; 6990bdb4f62Ssthen /** if the query is rpz passthru, no further rpz processing for it */ 7000bdb4f62Ssthen int rpz_passthru; 701d896b962Ssthen /* Flag tcp required. */ 702d896b962Ssthen int tcp_required; 7032be9e038Ssthen 7042be9e038Ssthen /** whether the reply should be dropped */ 7052be9e038Ssthen int is_drop; 706933707f3Ssthen }; 707933707f3Ssthen 708933707f3Ssthen /** 709933707f3Ssthen * Module functionality block 710933707f3Ssthen */ 711933707f3Ssthen struct module_func_block { 712933707f3Ssthen /** text string name of module */ 713933707f3Ssthen const char* name; 714933707f3Ssthen 715933707f3Ssthen /** 716*98bc733bSsthen * Set up the module for start. This is called only once at startup. 717*98bc733bSsthen * Privileged operations like opening device files may be done here. 718*98bc733bSsthen * The function ptr can be NULL, if it is not used. 719*98bc733bSsthen * @param env: module environment. 720*98bc733bSsthen * @param id: module id number. 721*98bc733bSsthen * return: 0 on error 722*98bc733bSsthen */ 723*98bc733bSsthen int (*startup)(struct module_env* env, int id); 724*98bc733bSsthen 725*98bc733bSsthen /** 726*98bc733bSsthen * Close down the module for stop. This is called only once before 727*98bc733bSsthen * shutdown to free resources allocated during startup(). 728*98bc733bSsthen * Closing privileged ports or files must be done here. 729*98bc733bSsthen * The function ptr can be NULL, if it is not used. 730*98bc733bSsthen * @param env: module environment. 731*98bc733bSsthen * @param id: module id number. 732*98bc733bSsthen */ 733*98bc733bSsthen void (*destartup)(struct module_env* env, int id); 734*98bc733bSsthen 735*98bc733bSsthen /** 736*98bc733bSsthen * Initialise the module. Called when restarting or reloading the 737*98bc733bSsthen * daemon. 738933707f3Ssthen * This is the place to apply settings from the config file. 739933707f3Ssthen * @param env: module environment. 740933707f3Ssthen * @param id: module id number. 741933707f3Ssthen * return: 0 on error 742933707f3Ssthen */ 743933707f3Ssthen int (*init)(struct module_env* env, int id); 744933707f3Ssthen 745933707f3Ssthen /** 746*98bc733bSsthen * Deinitialise the module, undo stuff done during init(). 747*98bc733bSsthen * Called before reloading the daemon. 748933707f3Ssthen * @param env: module environment. 749933707f3Ssthen * @param id: module id number. 750933707f3Ssthen */ 751933707f3Ssthen void (*deinit)(struct module_env* env, int id); 752933707f3Ssthen 753933707f3Ssthen /** 754933707f3Ssthen * accept a new query, or work further on existing query. 755933707f3Ssthen * Changes the qstate->ext_state to be correct on exit. 756933707f3Ssthen * @param ev: event that causes the module state machine to 757933707f3Ssthen * (re-)activate. 758933707f3Ssthen * @param qstate: the query state. 759933707f3Ssthen * Note that this method is not allowed to change the 760933707f3Ssthen * query state 'identity', that is query info, qflags, 761933707f3Ssthen * and priming status. 762933707f3Ssthen * Attach a subquery to get results to a different query. 763933707f3Ssthen * @param id: module id number that operate() is called on. 764933707f3Ssthen * @param outbound: if not NULL this event is due to the reply/timeout 765933707f3Ssthen * or error on this outbound query. 766933707f3Ssthen * @return: if at exit the ext_state is: 767933707f3Ssthen * o wait_module: next module is started. (with pass event). 768933707f3Ssthen * o error or finished: previous module is resumed. 769933707f3Ssthen * o otherwise it waits until that event happens (assumes 770933707f3Ssthen * the service routine to make subrequest or send message 771933707f3Ssthen * have been called. 772933707f3Ssthen */ 773933707f3Ssthen void (*operate)(struct module_qstate* qstate, enum module_ev event, 774933707f3Ssthen int id, struct outbound_entry* outbound); 775933707f3Ssthen 776933707f3Ssthen /** 777933707f3Ssthen * inform super querystate about the results from this subquerystate. 778933707f3Ssthen * Is called when the querystate is finished. The method invoked is 779933707f3Ssthen * the one from the current module active in the super querystate. 780933707f3Ssthen * @param qstate: the query state that is finished. 781933707f3Ssthen * Examine return_rcode and return_reply in the qstate. 782933707f3Ssthen * @param id: module id for this module. 783933707f3Ssthen * This coincides with the current module for the super qstate. 784933707f3Ssthen * @param super: the super querystate that needs to be informed. 785933707f3Ssthen */ 786933707f3Ssthen void (*inform_super)(struct module_qstate* qstate, int id, 787933707f3Ssthen struct module_qstate* super); 788933707f3Ssthen 789933707f3Ssthen /** 790933707f3Ssthen * clear module specific data 791933707f3Ssthen */ 792933707f3Ssthen void (*clear)(struct module_qstate* qstate, int id); 793933707f3Ssthen 794933707f3Ssthen /** 795933707f3Ssthen * How much memory is the module specific data using. 796933707f3Ssthen * @param env: module environment. 797933707f3Ssthen * @param id: the module id. 798933707f3Ssthen * @return the number of bytes that are alloced. 799933707f3Ssthen */ 800933707f3Ssthen size_t (*get_mem)(struct module_env* env, int id); 801933707f3Ssthen }; 802933707f3Ssthen 803933707f3Ssthen /** 804933707f3Ssthen * Debug utility: module external qstate to string 805933707f3Ssthen * @param s: the state value. 806933707f3Ssthen * @return descriptive string. 807933707f3Ssthen */ 808933707f3Ssthen const char* strextstate(enum module_ext_state s); 809933707f3Ssthen 810933707f3Ssthen /** 811933707f3Ssthen * Debug utility: module event to string 812933707f3Ssthen * @param e: the module event value. 813933707f3Ssthen * @return descriptive string. 814933707f3Ssthen */ 815933707f3Ssthen const char* strmodulevent(enum module_ev e); 816933707f3Ssthen 81777079be7Ssthen /** 8180bdb4f62Ssthen * Append text to the error info for validation. 8190bdb4f62Ssthen * @param qstate: query state. 8200bdb4f62Ssthen * @param str: copied into query region and appended. 8210bdb4f62Ssthen * Failures to allocate are logged. 8220bdb4f62Ssthen */ 8230bdb4f62Ssthen void errinf(struct module_qstate* qstate, const char* str); 8240bdb4f62Ssthen void errinf_ede(struct module_qstate* qstate, const char* str, 8250bdb4f62Ssthen sldns_ede_code reason_bogus); 8260bdb4f62Ssthen 8270bdb4f62Ssthen /** 8280bdb4f62Ssthen * Append text to error info: from 1.2.3.4 8290bdb4f62Ssthen * @param qstate: query state. 8300bdb4f62Ssthen * @param origin: sock list with origin of trouble. 8310bdb4f62Ssthen * Every element added. 8320bdb4f62Ssthen * If NULL: nothing is added. 8330bdb4f62Ssthen * if 0len element: 'from cache' is added. 8340bdb4f62Ssthen */ 8350bdb4f62Ssthen void errinf_origin(struct module_qstate* qstate, struct sock_list *origin); 8360bdb4f62Ssthen 8370bdb4f62Ssthen /** 8380bdb4f62Ssthen * Append text to error info: for RRset name type class 8390bdb4f62Ssthen * @param qstate: query state. 8400bdb4f62Ssthen * @param rr: rrset_key. 8410bdb4f62Ssthen */ 8420bdb4f62Ssthen void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr); 8430bdb4f62Ssthen 8440bdb4f62Ssthen /** 8450bdb4f62Ssthen * Append text to error info: str dname 8460bdb4f62Ssthen * @param qstate: query state. 8470bdb4f62Ssthen * @param str: explanation string 8480bdb4f62Ssthen * @param dname: the dname. 8490bdb4f62Ssthen */ 8500bdb4f62Ssthen void errinf_dname(struct module_qstate* qstate, const char* str, 8510bdb4f62Ssthen uint8_t* dname); 8520bdb4f62Ssthen 8530bdb4f62Ssthen /** 8540bdb4f62Ssthen * Create error info in string. For validation failures. 8550bdb4f62Ssthen * @param qstate: query state. 8562bdc0ed1Ssthen * @param region: the region for the result or NULL for malloced result. 8570bdb4f62Ssthen * @return string or NULL on malloc failure (already logged). 8582bdc0ed1Ssthen * This string is malloced if region is NULL and has to be freed by caller. 8590bdb4f62Ssthen */ 8602bdc0ed1Ssthen char* errinf_to_str_bogus(struct module_qstate* qstate, struct regional* region); 8618b7325afSsthen 8620bdb4f62Ssthen /** 8638b7325afSsthen * Check the sldns_ede_code of the qstate->errinf. 8640bdb4f62Ssthen * @param qstate: query state. 8658b7325afSsthen * @return the latest explicitly set sldns_ede_code or LDNS_EDE_NONE. 8660bdb4f62Ssthen */ 8670bdb4f62Ssthen sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate); 8680bdb4f62Ssthen 8690bdb4f62Ssthen /** 8700bdb4f62Ssthen * Create error info in string. For other servfails. 8710bdb4f62Ssthen * @param qstate: query state. 8720bdb4f62Ssthen * @return string or NULL on malloc failure (already logged). 8730bdb4f62Ssthen */ 8740bdb4f62Ssthen char* errinf_to_str_servfail(struct module_qstate* qstate); 8750bdb4f62Ssthen 8760bdb4f62Ssthen /** 877d896b962Ssthen * Create error info in string. For misc failures that are not servfail. 878d896b962Ssthen * @param qstate: query state. 879d896b962Ssthen * @return string or NULL on malloc failure (already logged). 880d896b962Ssthen */ 881d896b962Ssthen char* errinf_to_str_misc(struct module_qstate* qstate); 882d896b962Ssthen 883d896b962Ssthen /** 88477079be7Ssthen * Initialize the edns known options by allocating the required space. 88577079be7Ssthen * @param env: the module environment. 88677079be7Ssthen * @return false on failure (no memory). 88777079be7Ssthen */ 88877079be7Ssthen int edns_known_options_init(struct module_env* env); 88977079be7Ssthen 89077079be7Ssthen /** 89177079be7Ssthen * Free the allocated space for the known edns options. 89277079be7Ssthen * @param env: the module environment. 89377079be7Ssthen */ 89477079be7Ssthen void edns_known_options_delete(struct module_env* env); 89577079be7Ssthen 89677079be7Ssthen /** 89777079be7Ssthen * Register a known edns option. Overwrite the flags if it is already 89877079be7Ssthen * registered. Used before creating workers to register known edns options. 89977079be7Ssthen * @param opt_code: the edns option code. 90077079be7Ssthen * @param bypass_cache_stage: whether the option interacts with the cache. 90177079be7Ssthen * @param no_aggregation: whether the option implies more specific 90277079be7Ssthen * aggregation. 90377079be7Ssthen * @param env: the module environment. 90477079be7Ssthen * @return true on success, false on failure (registering more options than 90577079be7Ssthen * allowed or trying to register after the environment is copied to the 90677079be7Ssthen * threads.) 90777079be7Ssthen */ 90877079be7Ssthen int edns_register_option(uint16_t opt_code, int bypass_cache_stage, 90977079be7Ssthen int no_aggregation, struct module_env* env); 91077079be7Ssthen 91177079be7Ssthen /** 9122be9e038Ssthen * Register an inplace callback function. 91377079be7Ssthen * @param cb: pointer to the callback function. 9142be9e038Ssthen * @param type: inplace callback type. 9152be9e038Ssthen * @param cbarg: argument for the callback function, or NULL. 91677079be7Ssthen * @param env: the module environment. 9172be9e038Ssthen * @param id: module id. 91877079be7Ssthen * @return true on success, false on failure (out of memory or trying to 91977079be7Ssthen * register after the environment is copied to the threads.) 92077079be7Ssthen */ 9212be9e038Ssthen int 9222be9e038Ssthen inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg, 9232be9e038Ssthen struct module_env* env, int id); 92477079be7Ssthen 92577079be7Ssthen /** 9262be9e038Ssthen * Delete callback for specified type and module id. 92777079be7Ssthen * @param env: the module environment. 9282be9e038Ssthen * @param type: inplace callback type. 9292be9e038Ssthen * @param id: module id. 93077079be7Ssthen */ 9312be9e038Ssthen void 9322be9e038Ssthen inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type, 9332be9e038Ssthen int id); 93477079be7Ssthen 93577079be7Ssthen /** 93677079be7Ssthen * Delete all the inplace callback linked lists. 93777079be7Ssthen * @param env: the module environment. 93877079be7Ssthen */ 93977079be7Ssthen void inplace_cb_lists_delete(struct module_env* env); 94077079be7Ssthen 94177079be7Ssthen /** 94277079be7Ssthen * Check if an edns option is known. 94377079be7Ssthen * @param opt_code: the edns option code. 94477079be7Ssthen * @param env: the module environment. 94577079be7Ssthen * @return pointer to registered option if the edns option is known, 94677079be7Ssthen * NULL otherwise. 94777079be7Ssthen */ 94877079be7Ssthen struct edns_known_option* edns_option_is_known(uint16_t opt_code, 94977079be7Ssthen struct module_env* env); 95077079be7Ssthen 95177079be7Ssthen /** 95277079be7Ssthen * Check if an edns option needs to bypass the reply from cache stage. 95377079be7Ssthen * @param list: the edns options. 95477079be7Ssthen * @param env: the module environment. 95577079be7Ssthen * @return true if an edns option needs to bypass the cache stage, 95677079be7Ssthen * false otherwise. 95777079be7Ssthen */ 95877079be7Ssthen int edns_bypass_cache_stage(struct edns_option* list, 95977079be7Ssthen struct module_env* env); 96077079be7Ssthen 96177079be7Ssthen /** 9622be9e038Ssthen * Check if an unique mesh state is required. Might be triggered by EDNS option 9632be9e038Ssthen * or set for the complete env. 96477079be7Ssthen * @param list: the edns options. 96577079be7Ssthen * @param env: the module environment. 96677079be7Ssthen * @return true if an edns option needs a unique mesh state, 96777079be7Ssthen * false otherwise. 96877079be7Ssthen */ 9692be9e038Ssthen int unique_mesh_state(struct edns_option* list, struct module_env* env); 97077079be7Ssthen 97177079be7Ssthen /** 97277079be7Ssthen * Log the known edns options. 97377079be7Ssthen * @param level: the desired verbosity level. 97477079be7Ssthen * @param env: the module environment. 97577079be7Ssthen */ 97677079be7Ssthen void log_edns_known_options(enum verbosity_value level, 97777079be7Ssthen struct module_env* env); 97877079be7Ssthen 9792308e98cSsthen /** 9802308e98cSsthen * Copy state that may have happened in the subquery and is always relevant to 9812308e98cSsthen * the super. 9822308e98cSsthen * @param qstate: query state that finished. 9832308e98cSsthen * @param id: module id. 9842308e98cSsthen * @param super: the qstate to inform. 9852308e98cSsthen */ 9862308e98cSsthen void copy_state_to_super(struct module_qstate* qstate, int id, 9872308e98cSsthen struct module_qstate* super); 9882308e98cSsthen 989933707f3Ssthen #endif /* UTIL_MODULE_H */ 990