1238106Sdes/* 2238106Sdes * util/module.h - DNS handling module interface 3238106Sdes * 4238106Sdes * Copyright (c) 2007, NLnet Labs. All rights reserved. 5238106Sdes * 6238106Sdes * This software is open source. 7238106Sdes * 8238106Sdes * Redistribution and use in source and binary forms, with or without 9238106Sdes * modification, are permitted provided that the following conditions 10238106Sdes * are met: 11238106Sdes * 12238106Sdes * Redistributions of source code must retain the above copyright notice, 13238106Sdes * this list of conditions and the following disclaimer. 14238106Sdes * 15238106Sdes * Redistributions in binary form must reproduce the above copyright notice, 16238106Sdes * this list of conditions and the following disclaimer in the documentation 17238106Sdes * and/or other materials provided with the distribution. 18238106Sdes * 19238106Sdes * Neither the name of the NLNET LABS nor the names of its contributors may 20238106Sdes * be used to endorse or promote products derived from this software without 21238106Sdes * specific prior written permission. 22238106Sdes * 23238106Sdes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24269257Sdes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25269257Sdes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26269257Sdes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27269257Sdes * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28269257Sdes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29269257Sdes * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30269257Sdes * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31269257Sdes * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32269257Sdes * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33269257Sdes * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34238106Sdes */ 35238106Sdes 36238106Sdes/** 37238106Sdes * \file 38238106Sdes * 39238106Sdes * This file contains the interface for DNS handling modules. 40269257Sdes * 41269257Sdes * The module interface uses the DNS modules as state machines. The 42269257Sdes * state machines are activated in sequence to operate on queries. Once 43269257Sdes * they are done, the reply is passed back. In the usual setup the mesh 44269257Sdes * is the caller of the state machines and once things are done sends replies 45269257Sdes * and invokes result callbacks. 46269257Sdes * 47269257Sdes * The module provides a number of functions, listed in the module_func_block. 48269257Sdes * The module is inited and destroyed and memory usage queries, for the 49269257Sdes * module as a whole, for entire-module state (such as a cache). And per-query 50269257Sdes * functions are called, operate to move the state machine and cleanup of 51269257Sdes * the per-query state. 52269257Sdes * 53269257Sdes * Most per-query state should simply be allocated in the query region. 54269257Sdes * This is destroyed at the end of the query. 55269257Sdes * 56269257Sdes * The module environment contains services and information and caches 57269257Sdes * shared by the modules and the rest of the system. It also contains 58269257Sdes * function pointers for module-specific tasks (like sending queries). 59269257Sdes * 60269257Sdes * *** Example module calls for a normal query 61269257Sdes * 62269257Sdes * In this example, the query does not need recursion, all the other data 63269257Sdes * can be found in the cache. This makes the example shorter. 64269257Sdes * 65269257Sdes * At the start of the program the iterator module is initialised. 66269257Sdes * The iterator module sets up its global state, such as donotquery lists 67269257Sdes * and private address trees. 68269257Sdes * 69269257Sdes * A query comes in, and a mesh entry is created for it. The mesh 70269257Sdes * starts the resolution process. The validator module is the first 71269257Sdes * in the list of modules, and it is started on this new query. The 72269257Sdes * operate() function is called. The validator decides it needs not do 73269257Sdes * anything yet until there is a result and returns wait_module, that 74269257Sdes * causes the next module in the list to be started. 75269257Sdes * 76269257Sdes * The next module is the iterator. It is started on the passed query and 77269257Sdes * decides to perform a lookup. For this simple example, the delegation 78269257Sdes * point information is available, and all the iterator wants to do is 79269257Sdes * send a UDP query. The iterator uses env.send_query() to send the 80269257Sdes * query. Then the iterator suspends (returns from the operate call). 81269257Sdes * 82269257Sdes * When the UDP reply comes back (and on errors and timeouts), the 83269257Sdes * operate function is called for the query, on the iterator module, 84269257Sdes * with the event that there is a reply. The iterator decides that this 85269257Sdes * is enough, the work is done. It returns the value finished from the 86269257Sdes * operate call, which causes the previous module to be started. 87269257Sdes * 88269257Sdes * The previous module, the validator module, is started with the event 89269257Sdes * that the iterator module is done. The validator decides to validate 90269257Sdes * the query. Once it is done (which could take recursive lookups, but 91269257Sdes * in this example no recursive lookups are needed), it returns from the 92269257Sdes * operate function with finished. 93269257Sdes * 94269257Sdes * There is no previous module from the validator module, and the mesh 95269257Sdes * takes this to mean that the query is finally done. The mesh invokes 96269257Sdes * callbacks and sends packets to queriers. 97269257Sdes * 98269257Sdes * If other modules had been waiting (recursively) on the answer to this 99269257Sdes * query, then the mesh will tell them about it. It calls the inform_super 100269257Sdes * routine on all the waiting modules, and once that is done it calls all of 101269257Sdes * them with the operate() call. During inform_super the query that is done 102269257Sdes * still exists and information can be copied from it (but the module should 103269257Sdes * not really re-entry codepoints and services). During the operate call 104269257Sdes * the modules can use stored state to continue operation with the results. 105269257Sdes * (network buffers are used to contain the answer packet during the 106269257Sdes * inform_super phase, but after that the network buffers will be cleared 107269257Sdes * of their contents so that other tasks can be performed). 108269257Sdes * 109269257Sdes * *** Example module calls for recursion 110269257Sdes * 111269257Sdes * A module is called in operate, and it decides that it wants to perform 112269257Sdes * recursion. That is, it wants the full state-machine-list to operate on 113269257Sdes * a different query. It calls env.attach_sub() to create a new query state. 114269257Sdes * The routine returns the newly created state, and potentially the module 115269257Sdes * can edit the module-states for the newly created query (i.e. pass along 116269257Sdes * some information, like delegation points). The module then suspends, 117269257Sdes * returns from the operate routine. 118269257Sdes * 119269257Sdes * The mesh meanwhile will have the newly created query (or queries) on 120269257Sdes * a waiting list, and will call operate() on this query (or queries). 121269257Sdes * It starts again at the start of the module list for them. The query 122269257Sdes * (or queries) continue to operate their state machines, until they are 123269257Sdes * done. When they are done the mesh calls inform_super on the module that 124269257Sdes * wanted the recursion. After that the mesh calls operate() on the module 125269257Sdes * that wanted to do the recursion, and during this phase the module could, 126269257Sdes * for example, decide to create more recursions. 127269257Sdes * 128269257Sdes * If the module decides it no longer wants the recursive information 129269257Sdes * it can call detach_subs. Those queries will still run to completion, 130269257Sdes * potentially filling the cache with information. Inform_super is not 131269257Sdes * called any more. 132269257Sdes * 133269257Sdes * The iterator module will fetch items from the cache, so a recursion 134269257Sdes * attempt may complete very quickly if the item is in cache. The calling 135269257Sdes * module has to wait for completion or eventual timeout. A recursive query 136269257Sdes * that times out returns a servfail rcode (servfail is also returned for 137269257Sdes * other errors during the lookup). 138269257Sdes * 139269257Sdes * Results are passed in the qstate, the rcode member is used to pass 140269257Sdes * errors without requiring memory allocation, so that the code can continue 141269257Sdes * in out-of-memory conditions. If the rcode member is 0 (NOERROR) then 142269257Sdes * the dns_msg entry contains a filled out message. This message may 143269257Sdes * also contain an rcode that is nonzero, but in this case additional 144269257Sdes * information (query, additional) can be passed along. 145269257Sdes * 146269257Sdes * The rcode and dns_msg are used to pass the result from the the rightmost 147269257Sdes * module towards the leftmost modules and then towards the user. 148269257Sdes * 149269257Sdes * If you want to avoid recursion-cycles where queries need other queries 150269257Sdes * that need the first one, use detect_cycle() to see if that will happen. 151269257Sdes * 152238106Sdes */ 153238106Sdes 154238106Sdes#ifndef UTIL_MODULE_H 155238106Sdes#define UTIL_MODULE_H 156238106Sdes#include "util/storage/lruhash.h" 157238106Sdes#include "util/data/msgreply.h" 158238106Sdes#include "util/data/msgparse.h" 159269257Sdesstruct sldns_buffer; 160238106Sdesstruct alloc_cache; 161238106Sdesstruct rrset_cache; 162238106Sdesstruct key_cache; 163238106Sdesstruct config_file; 164238106Sdesstruct slabhash; 165238106Sdesstruct query_info; 166238106Sdesstruct edns_data; 167238106Sdesstruct regional; 168238106Sdesstruct worker; 169238106Sdesstruct module_qstate; 170238106Sdesstruct ub_randstate; 171238106Sdesstruct mesh_area; 172238106Sdesstruct mesh_state; 173238106Sdesstruct val_anchors; 174238106Sdesstruct val_neg_cache; 175238106Sdesstruct iter_forwards; 176238106Sdesstruct iter_hints; 177238106Sdes 178238106Sdes/** Maximum number of modules in operation */ 179238106Sdes#define MAX_MODULE 5 180238106Sdes 181238106Sdes/** 182238106Sdes * Module environment. 183238106Sdes * Services and data provided to the module. 184238106Sdes */ 185238106Sdesstruct module_env { 186238106Sdes /* --- data --- */ 187238106Sdes /** config file with config options */ 188238106Sdes struct config_file* cfg; 189238106Sdes /** shared message cache */ 190238106Sdes struct slabhash* msg_cache; 191238106Sdes /** shared rrset cache */ 192238106Sdes struct rrset_cache* rrset_cache; 193238106Sdes /** shared infrastructure cache (edns, lameness) */ 194238106Sdes struct infra_cache* infra_cache; 195238106Sdes /** shared key cache */ 196238106Sdes struct key_cache* key_cache; 197238106Sdes 198238106Sdes /* --- services --- */ 199238106Sdes /** 200238106Sdes * Send serviced DNS query to server. UDP/TCP and EDNS is handled. 201238106Sdes * operate() should return with wait_reply. Later on a callback 202238106Sdes * will cause operate() to be called with event timeout or reply. 203238106Sdes * The time until a timeout is calculated from roundtrip timing, 204238106Sdes * several UDP retries are attempted. 205238106Sdes * @param qname: query name. (host order) 206238106Sdes * @param qnamelen: length in bytes of qname, including trailing 0. 207238106Sdes * @param qtype: query type. (host order) 208238106Sdes * @param qclass: query class. (host order) 209238106Sdes * @param flags: host order flags word, with opcode and CD bit. 210238106Sdes * @param dnssec: if set, EDNS record will have bits set. 211238106Sdes * If EDNS_DO bit is set, DO bit is set in EDNS records. 212238106Sdes * If BIT_CD is set, CD bit is set in queries with EDNS records. 213238106Sdes * @param want_dnssec: if set, the validator wants DNSSEC. Without 214238106Sdes * EDNS, the answer is likely to be useless for this domain. 215285206Sdes * @param nocaps: do not use caps_for_id, use the qname as given. 216285206Sdes * (ignored if caps_for_id is disabled). 217238106Sdes * @param addr: where to. 218238106Sdes * @param addrlen: length of addr. 219238106Sdes * @param zone: delegation point name. 220238106Sdes * @param zonelen: length of zone name. 221238106Sdes * @param q: wich query state to reactivate upon return. 222238106Sdes * @return: false on failure (memory or socket related). no query was 223238106Sdes * sent. Or returns an outbound entry with qsent and qstate set. 224238106Sdes * This outbound_entry will be used on later module invocations 225238106Sdes * that involve this query (timeout, error or reply). 226238106Sdes */ 227238106Sdes struct outbound_entry* (*send_query)(uint8_t* qname, size_t qnamelen, 228238106Sdes uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, 229285206Sdes int want_dnssec, int nocaps, struct sockaddr_storage* addr, 230238106Sdes socklen_t addrlen, uint8_t* zone, size_t zonelen, 231238106Sdes struct module_qstate* q); 232238106Sdes 233238106Sdes /** 234238106Sdes * Detach-subqueries. 235238106Sdes * Remove all sub-query references from this query state. 236238106Sdes * Keeps super-references of those sub-queries correct. 237238106Sdes * Updates stat items in mesh_area structure. 238238106Sdes * @param qstate: used to find mesh state. 239238106Sdes */ 240238106Sdes void (*detach_subs)(struct module_qstate* qstate); 241238106Sdes 242238106Sdes /** 243238106Sdes * Attach subquery. 244238106Sdes * Creates it if it does not exist already. 245238106Sdes * Keeps sub and super references correct. 246238106Sdes * Updates stat items in mesh_area structure. 247238106Sdes * Pass if it is priming query or not. 248238106Sdes * return: 249238106Sdes * o if error (malloc) happened. 250238106Sdes * o need to initialise the new state (module init; it is a new state). 251238106Sdes * so that the next run of the query with this module is successful. 252238106Sdes * o no init needed, attachment successful. 253238106Sdes * 254238106Sdes * @param qstate: the state to find mesh state, and that wants to 255238106Sdes * receive the results from the new subquery. 256238106Sdes * @param qinfo: what to query for (copied). 257238106Sdes * @param qflags: what flags to use (RD, CD flag or not). 258238106Sdes * @param prime: if it is a (stub) priming query. 259285206Sdes * @param valrec: validation lookup recursion, does not need validation 260238106Sdes * @param newq: If the new subquery needs initialisation, it is 261238106Sdes * returned, otherwise NULL is returned. 262238106Sdes * @return: false on error, true if success (and init may be needed). 263238106Sdes */ 264238106Sdes int (*attach_sub)(struct module_qstate* qstate, 265238106Sdes struct query_info* qinfo, uint16_t qflags, int prime, 266285206Sdes int valrec, struct module_qstate** newq); 267238106Sdes 268238106Sdes /** 269238106Sdes * Kill newly attached sub. If attach_sub returns newq for 270238106Sdes * initialisation, but that fails, then this routine will cleanup and 271238106Sdes * delete the fresly created sub. 272238106Sdes * @param newq: the new subquery that is no longer needed. 273238106Sdes * It is removed. 274238106Sdes */ 275238106Sdes void (*kill_sub)(struct module_qstate* newq); 276238106Sdes 277238106Sdes /** 278238106Sdes * Detect if adding a dependency for qstate on name,type,class will 279238106Sdes * create a dependency cycle. 280238106Sdes * @param qstate: given mesh querystate. 281238106Sdes * @param qinfo: query info for dependency. 282238106Sdes * @param flags: query flags of dependency, RD/CD flags. 283238106Sdes * @param prime: if dependency is a priming query or not. 284285206Sdes * @param valrec: validation lookup recursion, does not need validation 285238106Sdes * @return true if the name,type,class exists and the given 286238106Sdes * qstate mesh exists as a dependency of that name. Thus 287238106Sdes * if qstate becomes dependent on name,type,class then a 288238106Sdes * cycle is created. 289238106Sdes */ 290238106Sdes int (*detect_cycle)(struct module_qstate* qstate, 291285206Sdes struct query_info* qinfo, uint16_t flags, int prime, 292285206Sdes int valrec); 293238106Sdes 294238106Sdes /** region for temporary usage. May be cleared after operate() call. */ 295238106Sdes struct regional* scratch; 296238106Sdes /** buffer for temporary usage. May be cleared after operate() call. */ 297269257Sdes struct sldns_buffer* scratch_buffer; 298238106Sdes /** internal data for daemon - worker thread. */ 299238106Sdes struct worker* worker; 300238106Sdes /** mesh area with query state dependencies */ 301238106Sdes struct mesh_area* mesh; 302238106Sdes /** allocation service */ 303238106Sdes struct alloc_cache* alloc; 304238106Sdes /** random table to generate random numbers */ 305238106Sdes struct ub_randstate* rnd; 306238106Sdes /** time in seconds, converted to integer */ 307269257Sdes time_t* now; 308238106Sdes /** time in microseconds. Relatively recent. */ 309238106Sdes struct timeval* now_tv; 310238106Sdes /** is validation required for messages, controls client-facing 311238106Sdes * validation status (AD bits) and servfails */ 312238106Sdes int need_to_validate; 313238106Sdes /** trusted key storage; these are the configured keys, if not NULL, 314238106Sdes * otherwise configured by validator. These are the trust anchors, 315238106Sdes * and are not primed and ready for validation, but on the bright 316238106Sdes * side, they are read only memory, thus no locks and fast. */ 317238106Sdes struct val_anchors* anchors; 318238106Sdes /** negative cache, configured by the validator. if not NULL, 319238106Sdes * contains NSEC record lookup trees. */ 320238106Sdes struct val_neg_cache* neg_cache; 321238106Sdes /** the 5011-probe timer (if any) */ 322238106Sdes struct comm_timer* probe_timer; 323238106Sdes /** Mapping of forwarding zones to targets. 324238106Sdes * iterator forwarder information. per-thread, created by worker */ 325238106Sdes struct iter_forwards* fwds; 326238106Sdes /** 327238106Sdes * iterator forwarder information. per-thread, created by worker. 328238106Sdes * The hints -- these aren't stored in the cache because they don't 329238106Sdes * expire. The hints are always used to "prime" the cache. Note 330238106Sdes * that both root hints and stub zone "hints" are stored in this 331238106Sdes * data structure. 332238106Sdes */ 333238106Sdes struct iter_hints* hints; 334238106Sdes /** module specific data. indexed by module id. */ 335238106Sdes void* modinfo[MAX_MODULE]; 336238106Sdes}; 337238106Sdes 338238106Sdes/** 339238106Sdes * External visible states of the module state machine 340238106Sdes * Modules may also have an internal state. 341238106Sdes * Modules are supposed to run to completion or until blocked. 342238106Sdes */ 343238106Sdesenum module_ext_state { 344238106Sdes /** initial state - new query */ 345238106Sdes module_state_initial = 0, 346238106Sdes /** waiting for reply to outgoing network query */ 347238106Sdes module_wait_reply, 348238106Sdes /** module is waiting for another module */ 349238106Sdes module_wait_module, 350238106Sdes /** module is waiting for another module; that other is restarted */ 351238106Sdes module_restart_next, 352238106Sdes /** module is waiting for sub-query */ 353238106Sdes module_wait_subquery, 354238106Sdes /** module could not finish the query */ 355238106Sdes module_error, 356238106Sdes /** module is finished with query */ 357238106Sdes module_finished 358238106Sdes}; 359238106Sdes 360238106Sdes/** 361238106Sdes * Events that happen to modules, that start or wakeup modules. 362238106Sdes */ 363238106Sdesenum module_ev { 364238106Sdes /** new query */ 365238106Sdes module_event_new = 0, 366238106Sdes /** query passed by other module */ 367238106Sdes module_event_pass, 368238106Sdes /** reply inbound from server */ 369238106Sdes module_event_reply, 370238106Sdes /** no reply, timeout or other error */ 371238106Sdes module_event_noreply, 372238106Sdes /** reply is there, but capitalisation check failed */ 373238106Sdes module_event_capsfail, 374238106Sdes /** next module is done, and its reply is awaiting you */ 375238106Sdes module_event_moddone, 376238106Sdes /** error */ 377238106Sdes module_event_error 378238106Sdes}; 379238106Sdes 380238106Sdes/** 381238106Sdes * Linked list of sockaddrs 382238106Sdes * May be allocated such that only 'len' bytes of addr exist for the structure. 383238106Sdes */ 384238106Sdesstruct sock_list { 385238106Sdes /** next in list */ 386238106Sdes struct sock_list* next; 387238106Sdes /** length of addr */ 388238106Sdes socklen_t len; 389238106Sdes /** sockaddr */ 390238106Sdes struct sockaddr_storage addr; 391238106Sdes}; 392238106Sdes 393238106Sdes/** 394238106Sdes * Module state, per query. 395238106Sdes */ 396238106Sdesstruct module_qstate { 397238106Sdes /** which query is being answered: name, type, class */ 398238106Sdes struct query_info qinfo; 399238106Sdes /** flags uint16 from query */ 400238106Sdes uint16_t query_flags; 401238106Sdes /** if this is a (stub or root) priming query (with hints) */ 402238106Sdes int is_priming; 403285206Sdes /** if this is a validation recursion query that does not get 404285206Sdes * validation itself */ 405285206Sdes int is_valrec; 406238106Sdes 407238106Sdes /** comm_reply contains server replies */ 408238106Sdes struct comm_reply* reply; 409238106Sdes /** the reply message, with message for client and calling module */ 410238106Sdes struct dns_msg* return_msg; 411238106Sdes /** the rcode, in case of error, instead of a reply message */ 412238106Sdes int return_rcode; 413238106Sdes /** origin of the reply (can be NULL from cache, list for cnames) */ 414238106Sdes struct sock_list* reply_origin; 415238106Sdes /** IP blacklist for queries */ 416238106Sdes struct sock_list* blacklist; 417238106Sdes /** region for this query. Cleared when query process finishes. */ 418238106Sdes struct regional* region; 419238106Sdes /** failure reason information if val-log-level is high */ 420238106Sdes struct config_strlist* errinf; 421238106Sdes 422238106Sdes /** which module is executing */ 423238106Sdes int curmod; 424238106Sdes /** module states */ 425238106Sdes enum module_ext_state ext_state[MAX_MODULE]; 426238106Sdes /** module specific data for query. indexed by module id. */ 427238106Sdes void* minfo[MAX_MODULE]; 428238106Sdes /** environment for this query */ 429238106Sdes struct module_env* env; 430238106Sdes /** mesh related information for this query */ 431238106Sdes struct mesh_state* mesh_info; 432238106Sdes /** how many seconds before expiry is this prefetched (0 if not) */ 433269257Sdes time_t prefetch_leeway; 434238106Sdes}; 435238106Sdes 436238106Sdes/** 437238106Sdes * Module functionality block 438238106Sdes */ 439238106Sdesstruct module_func_block { 440238106Sdes /** text string name of module */ 441238106Sdes const char* name; 442238106Sdes 443238106Sdes /** 444238106Sdes * init the module. Called once for the global state. 445238106Sdes * This is the place to apply settings from the config file. 446238106Sdes * @param env: module environment. 447238106Sdes * @param id: module id number. 448238106Sdes * return: 0 on error 449238106Sdes */ 450238106Sdes int (*init)(struct module_env* env, int id); 451238106Sdes 452238106Sdes /** 453238106Sdes * de-init, delete, the module. Called once for the global state. 454238106Sdes * @param env: module environment. 455238106Sdes * @param id: module id number. 456238106Sdes */ 457238106Sdes void (*deinit)(struct module_env* env, int id); 458238106Sdes 459238106Sdes /** 460238106Sdes * accept a new query, or work further on existing query. 461238106Sdes * Changes the qstate->ext_state to be correct on exit. 462238106Sdes * @param ev: event that causes the module state machine to 463238106Sdes * (re-)activate. 464238106Sdes * @param qstate: the query state. 465238106Sdes * Note that this method is not allowed to change the 466238106Sdes * query state 'identity', that is query info, qflags, 467238106Sdes * and priming status. 468238106Sdes * Attach a subquery to get results to a different query. 469238106Sdes * @param id: module id number that operate() is called on. 470238106Sdes * @param outbound: if not NULL this event is due to the reply/timeout 471238106Sdes * or error on this outbound query. 472238106Sdes * @return: if at exit the ext_state is: 473238106Sdes * o wait_module: next module is started. (with pass event). 474238106Sdes * o error or finished: previous module is resumed. 475238106Sdes * o otherwise it waits until that event happens (assumes 476238106Sdes * the service routine to make subrequest or send message 477238106Sdes * have been called. 478238106Sdes */ 479238106Sdes void (*operate)(struct module_qstate* qstate, enum module_ev event, 480238106Sdes int id, struct outbound_entry* outbound); 481238106Sdes 482238106Sdes /** 483238106Sdes * inform super querystate about the results from this subquerystate. 484238106Sdes * Is called when the querystate is finished. The method invoked is 485238106Sdes * the one from the current module active in the super querystate. 486238106Sdes * @param qstate: the query state that is finished. 487238106Sdes * Examine return_rcode and return_reply in the qstate. 488238106Sdes * @param id: module id for this module. 489238106Sdes * This coincides with the current module for the super qstate. 490238106Sdes * @param super: the super querystate that needs to be informed. 491238106Sdes */ 492238106Sdes void (*inform_super)(struct module_qstate* qstate, int id, 493238106Sdes struct module_qstate* super); 494238106Sdes 495238106Sdes /** 496238106Sdes * clear module specific data 497238106Sdes */ 498238106Sdes void (*clear)(struct module_qstate* qstate, int id); 499238106Sdes 500238106Sdes /** 501238106Sdes * How much memory is the module specific data using. 502238106Sdes * @param env: module environment. 503238106Sdes * @param id: the module id. 504238106Sdes * @return the number of bytes that are alloced. 505238106Sdes */ 506238106Sdes size_t (*get_mem)(struct module_env* env, int id); 507238106Sdes}; 508238106Sdes 509238106Sdes/** 510238106Sdes * Debug utility: module external qstate to string 511238106Sdes * @param s: the state value. 512238106Sdes * @return descriptive string. 513238106Sdes */ 514238106Sdesconst char* strextstate(enum module_ext_state s); 515238106Sdes 516238106Sdes/** 517238106Sdes * Debug utility: module event to string 518238106Sdes * @param e: the module event value. 519238106Sdes * @return descriptive string. 520238106Sdes */ 521238106Sdesconst char* strmodulevent(enum module_ev e); 522238106Sdes 523238106Sdes#endif /* UTIL_MODULE_H */ 524