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