module.h revision 307729
11590Srgrimes/* 21590Srgrimes * util/module.h - DNS handling module interface 31590Srgrimes * 41590Srgrimes * Copyright (c) 2007, NLnet Labs. All rights reserved. 51590Srgrimes * 61590Srgrimes * This software is open source. 71590Srgrimes * 81590Srgrimes * Redistribution and use in source and binary forms, with or without 91590Srgrimes * modification, are permitted provided that the following conditions 101590Srgrimes * are met: 111590Srgrimes * 121590Srgrimes * Redistributions of source code must retain the above copyright notice, 131590Srgrimes * this list of conditions and the following disclaimer. 141590Srgrimes * 151590Srgrimes * Redistributions in binary form must reproduce the above copyright notice, 161590Srgrimes * this list of conditions and the following disclaimer in the documentation 171590Srgrimes * and/or other materials provided with the distribution. 181590Srgrimes * 191590Srgrimes * Neither the name of the NLNET LABS nor the names of its contributors may 201590Srgrimes * be used to endorse or promote products derived from this software without 211590Srgrimes * specific prior written permission. 221590Srgrimes * 231590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 241590Srgrimes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 251590Srgrimes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 261590Srgrimes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 271590Srgrimes * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 281590Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 291590Srgrimes * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 301590Srgrimes * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3174769Smikeh * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3288150Smikeh * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3374769Smikeh * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 341590Srgrimes */ 3599112Sobrien 3699112Sobrien/** 371590Srgrimes * \file 381590Srgrimes * 391590Srgrimes * This file contains the interface for DNS handling modules. 401590Srgrimes * 411590Srgrimes * The module interface uses the DNS modules as state machines. The 421590Srgrimes * state machines are activated in sequence to operate on queries. Once 431590Srgrimes * they are done, the reply is passed back. In the usual setup the mesh 441590Srgrimes * is the caller of the state machines and once things are done sends replies 451590Srgrimes * and invokes result callbacks. 461590Srgrimes * 471590Srgrimes * The module provides a number of functions, listed in the module_func_block. 481590Srgrimes * The module is inited and destroyed and memory usage queries, for the 49173439Sdds * module as a whole, for entire-module state (such as a cache). And per-query 501590Srgrimes * functions are called, operate to move the state machine and cleanup of 5177274Smikeh * the per-query state. 5277274Smikeh * 5377274Smikeh * Most per-query state should simply be allocated in the query region. 541590Srgrimes * This is destroyed at the end of the query. 551590Srgrimes * 561590Srgrimes * The module environment contains services and information and caches 571590Srgrimes * shared by the modules and the rest of the system. It also contains 581590Srgrimes * function pointers for module-specific tasks (like sending queries). 59126415Smikeh * 60126415Smikeh * *** Example module calls for a normal query 61126415Smikeh * 62126415Smikeh * In this example, the query does not need recursion, all the other data 631590Srgrimes * can be found in the cache. This makes the example shorter. 641590Srgrimes * 65216564Scharnier * At the start of the program the iterator module is initialised. 661590Srgrimes * The iterator module sets up its global state, such as donotquery lists 671590Srgrimes * and private address trees. 68126415Smikeh * 691590Srgrimes * A query comes in, and a mesh entry is created for it. The mesh 7088150Smikeh * starts the resolution process. The validator module is the first 711590Srgrimes * in the list of modules, and it is started on this new query. The 7274769Smikeh * operate() function is called. The validator decides it needs not do 731590Srgrimes * anything yet until there is a result and returns wait_module, that 741590Srgrimes * causes the next module in the list to be started. 75126691Smikeh * 7677274Smikeh * The next module is the iterator. It is started on the passed query and 7777274Smikeh * decides to perform a lookup. For this simple example, the delegation 781590Srgrimes * point information is available, and all the iterator wants to do is 791590Srgrimes * send a UDP query. The iterator uses env.send_query() to send the 801590Srgrimes * query. Then the iterator suspends (returns from the operate call). 811590Srgrimes * 8274769Smikeh * When the UDP reply comes back (and on errors and timeouts), the 8377274Smikeh * operate function is called for the query, on the iterator module, 841590Srgrimes * with the event that there is a reply. The iterator decides that this 851590Srgrimes * is enough, the work is done. It returns the value finished from the 861590Srgrimes * operate call, which causes the previous module to be started. 8774769Smikeh * 8877274Smikeh * The previous module, the validator module, is started with the event 891590Srgrimes * that the iterator module is done. The validator decides to validate 901590Srgrimes * the query. Once it is done (which could take recursive lookups, but 911590Srgrimes * in this example no recursive lookups are needed), it returns from the 9274769Smikeh * operate function with finished. 9377274Smikeh * 9474769Smikeh * There is no previous module from the validator module, and the mesh 9574769Smikeh * takes this to mean that the query is finally done. The mesh invokes 961590Srgrimes * callbacks and sends packets to queriers. 971590Srgrimes * 981590Srgrimes * If other modules had been waiting (recursively) on the answer to this 991590Srgrimes * query, then the mesh will tell them about it. It calls the inform_super 1001590Srgrimes * routine on all the waiting modules, and once that is done it calls all of 1011590Srgrimes * them with the operate() call. During inform_super the query that is done 1021590Srgrimes * still exists and information can be copied from it (but the module should 1031590Srgrimes * not really re-entry codepoints and services). During the operate call 1041590Srgrimes * the modules can use stored state to continue operation with the results. 1051590Srgrimes * (network buffers are used to contain the answer packet during the 1061590Srgrimes * inform_super phase, but after that the network buffers will be cleared 1071590Srgrimes * of their contents so that other tasks can be performed). 1081590Srgrimes * 1091590Srgrimes * *** Example module calls for recursion 1101590Srgrimes * 1111590Srgrimes * A module is called in operate, and it decides that it wants to perform 1121590Srgrimes * recursion. That is, it wants the full state-machine-list to operate on 1131590Srgrimes * a different query. It calls env.attach_sub() to create a new query state. 1141590Srgrimes * The routine returns the newly created state, and potentially the module 1151590Srgrimes * can edit the module-states for the newly created query (i.e. pass along 1161590Srgrimes * some information, like delegation points). The module then suspends, 1171590Srgrimes * returns from the operate routine. 1181590Srgrimes * 11977274Smikeh * The mesh meanwhile will have the newly created query (or queries) on 1201590Srgrimes * a waiting list, and will call operate() on this query (or queries). 12177274Smikeh * It starts again at the start of the module list for them. The query 12277274Smikeh * (or queries) continue to operate their state machines, until they are 1231590Srgrimes * done. When they are done the mesh calls inform_super on the module that 1241590Srgrimes * wanted the recursion. After that the mesh calls operate() on the module 1251590Srgrimes * that wanted to do the recursion, and during this phase the module could, 12674769Smikeh * for example, decide to create more recursions. 1271590Srgrimes * 12874769Smikeh * If the module decides it no longer wants the recursive information 1291590Srgrimes * it can call detach_subs. Those queries will still run to completion, 13077274Smikeh * potentially filling the cache with information. Inform_super is not 13177274Smikeh * called any more. 13274769Smikeh * 13374769Smikeh * The iterator module will fetch items from the cache, so a recursion 13477274Smikeh * attempt may complete very quickly if the item is in cache. The calling 13574769Smikeh * module has to wait for completion or eventual timeout. A recursive query 13674769Smikeh * that times out returns a servfail rcode (servfail is also returned for 13777274Smikeh * other errors during the lookup). 13877274Smikeh * 13988150Smikeh * Results are passed in the qstate, the rcode member is used to pass 1401590Srgrimes * errors without requiring memory allocation, so that the code can continue 14188150Smikeh * in out-of-memory conditions. If the rcode member is 0 (NOERROR) then 14288150Smikeh * the dns_msg entry contains a filled out message. This message may 14388150Smikeh * also contain an rcode that is nonzero, but in this case additional 14488150Smikeh * information (query, additional) can be passed along. 14588150Smikeh * 14688227Sache * The rcode and dns_msg are used to pass the result from the the rightmost 14777274Smikeh * module towards the leftmost modules and then towards the user. 1481590Srgrimes * 1491590Srgrimes * If you want to avoid recursion-cycles where queries need other queries 150126415Smikeh * that need the first one, use detect_cycle() to see if that will happen. 151126415Smikeh * 1521590Srgrimes */ 153126415Smikeh 154126415Smikeh#ifndef UTIL_MODULE_H 155126415Smikeh#define UTIL_MODULE_H 156126415Smikeh#include "util/storage/lruhash.h" 157126415Smikeh#include "util/data/msgreply.h" 1581590Srgrimes#include "util/data/msgparse.h" 159126415Smikehstruct sldns_buffer; 1601590Srgrimesstruct alloc_cache; 1611590Srgrimesstruct rrset_cache; 16288150Smikehstruct key_cache; 16388150Smikehstruct config_file; 16488150Smikehstruct slabhash; 16588150Smikehstruct query_info; 16688150Smikehstruct edns_data; 167216564Scharnierstruct regional; 16888150Smikehstruct worker; 16988227Sachestruct module_qstate; 17088150Smikehstruct ub_randstate; 17188150Smikehstruct mesh_area; 17288150Smikehstruct mesh_state; 17388150Smikehstruct val_anchors; 17488150Smikehstruct val_neg_cache; 17588150Smikehstruct iter_forwards; 17688150Smikehstruct iter_hints; 17788150Smikeh 17888150Smikeh/** Maximum number of modules in operation */ 17988150Smikeh#define MAX_MODULE 5 18088150Smikeh 18188150Smikeh/** 18288150Smikeh * Module environment. 18388150Smikeh * Services and data provided to the module. 18488150Smikeh */ 18588150Smikehstruct module_env { 18688227Sache /* --- data --- */ 18788150Smikeh /** config file with config options */ 18888150Smikeh struct config_file* cfg; 18988150Smikeh /** shared message cache */ 19088150Smikeh struct slabhash* msg_cache; 19188150Smikeh /** shared rrset cache */ 192173439Sdds struct rrset_cache* rrset_cache; 193173439Sdds /** shared infrastructure cache (edns, lameness) */ 1941590Srgrimes struct infra_cache* infra_cache; 1951590Srgrimes /** shared key cache */ 1961590Srgrimes struct key_cache* key_cache; 1971590Srgrimes 1981590Srgrimes /* --- services --- */ 1991590Srgrimes /** 200216564Scharnier * Send serviced DNS query to server. UDP/TCP and EDNS is handled. 2011590Srgrimes * operate() should return with wait_reply. Later on a callback 20277274Smikeh * will cause operate() to be called with event timeout or reply. 2031590Srgrimes * The time until a timeout is calculated from roundtrip timing, 2041590Srgrimes * several UDP retries are attempted. 2051590Srgrimes * @param qname: query name. (host order) 2061590Srgrimes * @param qnamelen: length in bytes of qname, including trailing 0. 20777274Smikeh * @param qtype: query type. (host order) 2081590Srgrimes * @param qclass: query class. (host order) 20977274Smikeh * @param flags: host order flags word, with opcode and CD bit. 21077274Smikeh * @param dnssec: if set, EDNS record will have bits set. 21177274Smikeh * If EDNS_DO bit is set, DO bit is set in EDNS records. 21277274Smikeh * If BIT_CD is set, CD bit is set in queries with EDNS records. 2131590Srgrimes * @param want_dnssec: if set, the validator wants DNSSEC. Without 2141590Srgrimes * EDNS, the answer is likely to be useless for this domain. 2151590Srgrimes * @param nocaps: do not use caps_for_id, use the qname as given. 2161590Srgrimes * (ignored if caps_for_id is disabled). 2171590Srgrimes * @param opt_list: set these EDNS options on the outgoing packet. 2181590Srgrimes * or NULL if none (the list is deep-copied). 2191590Srgrimes * @param addr: where to. 22077274Smikeh * @param addrlen: length of addr. 22188150Smikeh * @param zone: delegation point name. 22288150Smikeh * @param zonelen: length of zone name. 2231590Srgrimes * @param q: wich query state to reactivate upon return. 22469249Skris * @return: false on failure (memory or socket related). no query was 2251590Srgrimes * sent. Or returns an outbound entry with qsent and qstate set. 22677274Smikeh * This outbound_entry will be used on later module invocations 2271590Srgrimes * that involve this query (timeout, error or reply). 2281590Srgrimes */ 2291590Srgrimes struct outbound_entry* (*send_query)(uint8_t* qname, size_t qnamelen, 2301590Srgrimes uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, 2311590Srgrimes int want_dnssec, int nocaps, struct edns_option* opt_list, 2321590Srgrimes struct sockaddr_storage* addr, socklen_t addrlen, 2331590Srgrimes uint8_t* zone, size_t zonelen, struct module_qstate* q); 2341590Srgrimes 2351590Srgrimes /** 2361590Srgrimes * Detach-subqueries. 2371590Srgrimes * Remove all sub-query references from this query state. 2381590Srgrimes * Keeps super-references of those sub-queries correct. 2391590Srgrimes * Updates stat items in mesh_area structure. 2401590Srgrimes * @param qstate: used to find mesh state. 2411590Srgrimes */ 2421590Srgrimes void (*detach_subs)(struct module_qstate* qstate); 2431590Srgrimes 2441590Srgrimes /** 2451590Srgrimes * Attach subquery. 2461590Srgrimes * Creates it if it does not exist already. 2471590Srgrimes * Keeps sub and super references correct. 2481590Srgrimes * Updates stat items in mesh_area structure. 2491590Srgrimes * Pass if it is priming query or not. 2501590Srgrimes * return: 2511590Srgrimes * o if error (malloc) happened. 2521590Srgrimes * o need to initialise the new state (module init; it is a new state). 2531590Srgrimes * so that the next run of the query with this module is successful. 2541590Srgrimes * o no init needed, attachment successful. 25577274Smikeh * 25677274Smikeh * @param qstate: the state to find mesh state, and that wants to 2571590Srgrimes * receive the results from the new subquery. 2581590Srgrimes * @param qinfo: what to query for (copied). 2591590Srgrimes * @param qflags: what flags to use (RD, CD flag or not). 2601590Srgrimes * @param prime: if it is a (stub) priming query. 2611590Srgrimes * @param valrec: validation lookup recursion, does not need validation 2621590Srgrimes * @param newq: If the new subquery needs initialisation, it is 2631590Srgrimes * returned, otherwise NULL is returned. 2641590Srgrimes * @return: false on error, true if success (and init may be needed). 2651590Srgrimes */ 2661590Srgrimes int (*attach_sub)(struct module_qstate* qstate, 2671590Srgrimes struct query_info* qinfo, uint16_t qflags, int prime, 2681590Srgrimes int valrec, struct module_qstate** newq); 2691590Srgrimes 2701590Srgrimes /** 2711590Srgrimes * Kill newly attached sub. If attach_sub returns newq for 2721590Srgrimes * initialisation, but that fails, then this routine will cleanup and 2731590Srgrimes * delete the fresly created sub. 2741590Srgrimes * @param newq: the new subquery that is no longer needed. 2751590Srgrimes * It is removed. 2761590Srgrimes */ 277216564Scharnier void (*kill_sub)(struct module_qstate* newq); 2781590Srgrimes 2791590Srgrimes /** 2801590Srgrimes * Detect if adding a dependency for qstate on name,type,class will 28177274Smikeh * create a dependency cycle. 28277274Smikeh * @param qstate: given mesh querystate. 28377274Smikeh * @param qinfo: query info for dependency. 2841590Srgrimes * @param flags: query flags of dependency, RD/CD flags. 2851590Srgrimes * @param prime: if dependency is a priming query or not. 2861590Srgrimes * @param valrec: validation lookup recursion, does not need validation 2871590Srgrimes * @return true if the name,type,class exists and the given 2881590Srgrimes * qstate mesh exists as a dependency of that name. Thus 2891590Srgrimes * if qstate becomes dependent on name,type,class then a 2901590Srgrimes * cycle is created. 2911590Srgrimes */ 2921590Srgrimes int (*detect_cycle)(struct module_qstate* qstate, 2931590Srgrimes struct query_info* qinfo, uint16_t flags, int prime, 2941590Srgrimes int valrec); 29588227Sache 2961590Srgrimes /** region for temporary usage. May be cleared after operate() call. */ 2971590Srgrimes struct regional* scratch; 2981590Srgrimes /** buffer for temporary usage. May be cleared after operate() call. */ 2991590Srgrimes struct sldns_buffer* scratch_buffer; 3001590Srgrimes /** internal data for daemon - worker thread. */ 3011590Srgrimes struct worker* worker; 3021590Srgrimes /** mesh area with query state dependencies */ 30377274Smikeh struct mesh_area* mesh; 3041590Srgrimes /** allocation service */ 3051590Srgrimes struct alloc_cache* alloc; 30677274Smikeh /** random table to generate random numbers */ 3071590Srgrimes struct ub_randstate* rnd; 3081590Srgrimes /** time in seconds, converted to integer */ 3091590Srgrimes time_t* now; 3101590Srgrimes /** time in microseconds. Relatively recent. */ 3111590Srgrimes struct timeval* now_tv; 3121590Srgrimes /** is validation required for messages, controls client-facing 3131590Srgrimes * validation status (AD bits) and servfails */ 3141590Srgrimes int need_to_validate; 3151590Srgrimes /** trusted key storage; these are the configured keys, if not NULL, 3161590Srgrimes * otherwise configured by validator. These are the trust anchors, 3171590Srgrimes * and are not primed and ready for validation, but on the bright 3181590Srgrimes * side, they are read only memory, thus no locks and fast. */ 31977274Smikeh struct val_anchors* anchors; 3201590Srgrimes /** negative cache, configured by the validator. if not NULL, 32177274Smikeh * contains NSEC record lookup trees. */ 3221590Srgrimes struct val_neg_cache* neg_cache; 3231590Srgrimes /** the 5011-probe timer (if any) */ 3241590Srgrimes struct comm_timer* probe_timer; 3251590Srgrimes /** Mapping of forwarding zones to targets. 3261590Srgrimes * iterator forwarder information. per-thread, created by worker */ 3271590Srgrimes struct iter_forwards* fwds; 3281590Srgrimes /** 3291590Srgrimes * iterator forwarder information. per-thread, created by worker. 3301590Srgrimes * The hints -- these aren't stored in the cache because they don't 3311590Srgrimes * expire. The hints are always used to "prime" the cache. Note 33277274Smikeh * that both root hints and stub zone "hints" are stored in this 33377274Smikeh * data structure. 3341590Srgrimes */ 3351590Srgrimes struct iter_hints* hints; 3361590Srgrimes /** module specific data. indexed by module id. */ 3371590Srgrimes void* modinfo[MAX_MODULE]; 3381590Srgrimes}; 3391590Srgrimes 3401590Srgrimes/** 3411590Srgrimes * External visible states of the module state machine 3421590Srgrimes * Modules may also have an internal state. 3431590Srgrimes * Modules are supposed to run to completion or until blocked. 3441590Srgrimes */ 3451590Srgrimesenum module_ext_state { 3461590Srgrimes /** initial state - new query */ 3471590Srgrimes module_state_initial = 0, 3481590Srgrimes /** waiting for reply to outgoing network query */ 3491590Srgrimes module_wait_reply, 3501590Srgrimes /** module is waiting for another module */ 3511590Srgrimes module_wait_module, 3521590Srgrimes /** module is waiting for another module; that other is restarted */ 3531590Srgrimes module_restart_next, 3541590Srgrimes /** module is waiting for sub-query */ 3551590Srgrimes module_wait_subquery, 3561590Srgrimes /** module could not finish the query */ 3571590Srgrimes module_error, 3581590Srgrimes /** module is finished with query */ 3591590Srgrimes module_finished 3601590Srgrimes}; 3611590Srgrimes 3621590Srgrimes/** 3631590Srgrimes * Events that happen to modules, that start or wakeup modules. 3641590Srgrimes */ 3651590Srgrimesenum module_ev { 3661590Srgrimes /** new query */ 3671590Srgrimes module_event_new = 0, 3681590Srgrimes /** query passed by other module */ 3691590Srgrimes module_event_pass, 3701590Srgrimes /** reply inbound from server */ 3711590Srgrimes module_event_reply, 3721590Srgrimes /** no reply, timeout or other error */ 3731590Srgrimes module_event_noreply, 37477274Smikeh /** reply is there, but capitalisation check failed */ 37529574Sphk module_event_capsfail, 3761590Srgrimes /** next module is done, and its reply is awaiting you */ 37729574Sphk module_event_moddone, 3781590Srgrimes /** error */ 3791590Srgrimes module_event_error 3801590Srgrimes}; 3811590Srgrimes 3821590Srgrimes/** 3831590Srgrimes * Linked list of sockaddrs 3841590Srgrimes * May be allocated such that only 'len' bytes of addr exist for the structure. 3851590Srgrimes */ 3861590Srgrimesstruct sock_list { 3871590Srgrimes /** next in list */ 3881590Srgrimes struct sock_list* next; 3891590Srgrimes /** length of addr */ 3901590Srgrimes socklen_t len; 3911590Srgrimes /** sockaddr */ 3921590Srgrimes struct sockaddr_storage addr; 3931590Srgrimes}; 3941590Srgrimes 3951590Srgrimes/** 3961590Srgrimes * Module state, per query. 3971590Srgrimes */ 3981590Srgrimesstruct module_qstate { 3991590Srgrimes /** which query is being answered: name, type, class */ 4001590Srgrimes struct query_info qinfo; 4011590Srgrimes /** flags uint16 from query */ 4021590Srgrimes uint16_t query_flags; 40388227Sache /** if this is a (stub or root) priming query (with hints) */ 4041590Srgrimes int is_priming; 4051590Srgrimes /** if this is a validation recursion query that does not get 4061590Srgrimes * validation itself */ 4071590Srgrimes int is_valrec; 4081590Srgrimes 4091590Srgrimes /** comm_reply contains server replies */ 4101590Srgrimes struct comm_reply* reply; 4111590Srgrimes /** the reply message, with message for client and calling module */ 4121590Srgrimes struct dns_msg* return_msg; 41377274Smikeh /** the rcode, in case of error, instead of a reply message */ 4141590Srgrimes int return_rcode; 4151590Srgrimes /** origin of the reply (can be NULL from cache, list for cnames) */ 4161590Srgrimes struct sock_list* reply_origin; 41777274Smikeh /** IP blacklist for queries */ 4181590Srgrimes struct sock_list* blacklist; 4191590Srgrimes /** region for this query. Cleared when query process finishes. */ 4201590Srgrimes struct regional* region; 4211590Srgrimes /** failure reason information if val-log-level is high */ 42277274Smikeh struct config_strlist* errinf; 4231590Srgrimes 4241590Srgrimes /** which module is executing */ 4251590Srgrimes int curmod; 4261590Srgrimes /** module states */ 4271590Srgrimes enum module_ext_state ext_state[MAX_MODULE]; 4281590Srgrimes /** module specific data for query. indexed by module id. */ 4291590Srgrimes void* minfo[MAX_MODULE]; 4301590Srgrimes /** environment for this query */ 4311590Srgrimes struct module_env* env; 4321590Srgrimes /** mesh related information for this query */ 4331590Srgrimes struct mesh_state* mesh_info; 4341590Srgrimes /** how many seconds before expiry is this prefetched (0 if not) */ 4351590Srgrimes time_t prefetch_leeway; 4361590Srgrimes}; 43774769Smikeh 4381590Srgrimes/** 4391590Srgrimes * Module functionality block 4401590Srgrimes */ 4411590Srgrimesstruct module_func_block { 4421590Srgrimes /** text string name of module */ 4431590Srgrimes const char* name; 4441590Srgrimes 4451590Srgrimes /** 4461590Srgrimes * init the module. Called once for the global state. 44777274Smikeh * This is the place to apply settings from the config file. 4481590Srgrimes * @param env: module environment. 44977274Smikeh * @param id: module id number. 4501590Srgrimes * return: 0 on error 4511590Srgrimes */ 45277274Smikeh int (*init)(struct module_env* env, int id); 4531590Srgrimes 45488150Smikeh /** 45588150Smikeh * de-init, delete, the module. Called once for the global state. 45677274Smikeh * @param env: module environment. 4571590Srgrimes * @param id: module id number. 4581590Srgrimes */ 4591590Srgrimes void (*deinit)(struct module_env* env, int id); 4601590Srgrimes 4611590Srgrimes /** 4621590Srgrimes * accept a new query, or work further on existing query. 4631590Srgrimes * Changes the qstate->ext_state to be correct on exit. 46477274Smikeh * @param ev: event that causes the module state machine to 4651590Srgrimes * (re-)activate. 4661590Srgrimes * @param qstate: the query state. 4671590Srgrimes * Note that this method is not allowed to change the 4681590Srgrimes * query state 'identity', that is query info, qflags, 4691590Srgrimes * and priming status. 4701590Srgrimes * Attach a subquery to get results to a different query. 4711590Srgrimes * @param id: module id number that operate() is called on. 472216564Scharnier * @param outbound: if not NULL this event is due to the reply/timeout 4731590Srgrimes * or error on this outbound query. 4741590Srgrimes * @return: if at exit the ext_state is: 47588150Smikeh * o wait_module: next module is started. (with pass event). 47677274Smikeh * o error or finished: previous module is resumed. 47777274Smikeh * o otherwise it waits until that event happens (assumes 4781590Srgrimes * the service routine to make subrequest or send message 4791590Srgrimes * have been called. 4801590Srgrimes */ 4811590Srgrimes void (*operate)(struct module_qstate* qstate, enum module_ev event, 4821590Srgrimes int id, struct outbound_entry* outbound); 4831590Srgrimes 4841590Srgrimes /** 485228468Sed * inform super querystate about the results from this subquerystate. 486216564Scharnier * Is called when the querystate is finished. The method invoked is 4871590Srgrimes * the one from the current module active in the super querystate. 48877274Smikeh * @param qstate: the query state that is finished. 4891590Srgrimes * Examine return_rcode and return_reply in the qstate. 49010067Sjoerg * @param id: module id for this module. 49177274Smikeh * This coincides with the current module for the super qstate. 49210067Sjoerg * @param super: the super querystate that needs to be informed. 49310067Sjoerg */ 49474769Smikeh void (*inform_super)(struct module_qstate* qstate, int id, 49510067Sjoerg struct module_qstate* super); 49610067Sjoerg 49710067Sjoerg /** 49810067Sjoerg * clear module specific data 49910067Sjoerg */ 50010067Sjoerg void (*clear)(struct module_qstate* qstate, int id); 50177274Smikeh 5021590Srgrimes /** 50377274Smikeh * How much memory is the module specific data using. 50477274Smikeh * @param env: module environment. 5051590Srgrimes * @param id: the module id. 5061590Srgrimes * @return the number of bytes that are alloced. 5071590Srgrimes */ 5081590Srgrimes size_t (*get_mem)(struct module_env* env, int id); 5091590Srgrimes}; 5101590Srgrimes 5111590Srgrimes/** 512216564Scharnier * Debug utility: module external qstate to string 5131590Srgrimes * @param s: the state value. 51477274Smikeh * @return descriptive string. 5151590Srgrimes */ 5161590Srgrimesconst char* strextstate(enum module_ext_state s); 5171590Srgrimes 5181590Srgrimes/** 5191590Srgrimes * Debug utility: module event to string 52077274Smikeh * @param e: the module event value. 52177274Smikeh * @return descriptive string. 5221590Srgrimes */ 5231590Srgrimesconst char* strmodulevent(enum module_ev e); 5241590Srgrimes 5251590Srgrimes#endif /* UTIL_MODULE_H */ 5261590Srgrimes