mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- code documentation on the module interface.
git-svn-id: file:///svn/unbound/trunk@3074 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
3997b79936
commit
5865ec4067
2 changed files with 113 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
6 February 2014: Wouter
|
6 February 2014: Wouter
|
||||||
- sldns has type HIP.
|
- sldns has type HIP.
|
||||||
|
- code documentation on the module interface.
|
||||||
|
|
||||||
5 February 2014: Wouter
|
5 February 2014: Wouter
|
||||||
- Fix sldns parse tests on osx.
|
- Fix sldns parse tests on osx.
|
||||||
|
|
|
||||||
112
util/module.h
112
util/module.h
|
|
@ -37,6 +37,118 @@
|
||||||
* \file
|
* \file
|
||||||
*
|
*
|
||||||
* This file contains the interface for DNS handling modules.
|
* This file contains the interface for DNS handling modules.
|
||||||
|
*
|
||||||
|
* The module interface uses the DNS modules as state machines. The
|
||||||
|
* state machines are activated in sequence to operate on queries. Once
|
||||||
|
* they are done, the reply is passed back. In the usual setup the mesh
|
||||||
|
* is the caller of the state machines and once things are done sends replies
|
||||||
|
* and invokes result callbacks.
|
||||||
|
*
|
||||||
|
* The module provides a number of functions, listed in the module_func_block.
|
||||||
|
* The module is inited and destroyed and memory usage queries, for the
|
||||||
|
* module as a whole, for entire-module state (such as a cache). And per-query
|
||||||
|
* functions are called, operate to move the state machine and cleanup of
|
||||||
|
* the per-query state.
|
||||||
|
*
|
||||||
|
* Most per-query state should simply be allocated in the query region.
|
||||||
|
* This is destroyed at the end of the query.
|
||||||
|
*
|
||||||
|
* The module environment contains services and information and caches
|
||||||
|
* shared by the modules and the rest of the system. It also contains
|
||||||
|
* function pointers for module-specific tasks (like sending queries).
|
||||||
|
*
|
||||||
|
* *** Example module calls for a normal query
|
||||||
|
*
|
||||||
|
* In this example, the query does not need recursion, all the other data
|
||||||
|
* can be found in the cache. This makes the example shorter.
|
||||||
|
*
|
||||||
|
* At the start of the program the iterator module is initialised.
|
||||||
|
* The iterator module sets up its global state, such as donotquery lists
|
||||||
|
* and private address trees.
|
||||||
|
*
|
||||||
|
* A query comes in, and a mesh entry is created for it. The mesh
|
||||||
|
* starts the resolution process. The validator module is the first
|
||||||
|
* in the list of modules, and it is started on this new query. The
|
||||||
|
* operate() function is called. The validator decides it needs not do
|
||||||
|
* anything yet until there is a result and returns wait_module, that
|
||||||
|
* causes the next module in the list to be started.
|
||||||
|
*
|
||||||
|
* The next module is the iterator. It is started on the passed query and
|
||||||
|
* decides to perform a lookup. For this simple example, the delegation
|
||||||
|
* point information is available, and all the iterator wants to do is
|
||||||
|
* send a UDP query. The iterator uses env.send_query() to send the
|
||||||
|
* query. Then the iterator suspends (returns from the operate call).
|
||||||
|
*
|
||||||
|
* When the UDP reply comes back (and on errors and timeouts), the
|
||||||
|
* operate function is called for the query, on the iterator module,
|
||||||
|
* with the event that there is a reply. The iterator decides that this
|
||||||
|
* is enough, the work is done. It returns the value finished from the
|
||||||
|
* operate call, which causes the previous module to be started.
|
||||||
|
*
|
||||||
|
* The previous module, the validator module, is started with the event
|
||||||
|
* that the iterator module is done. The validator decides to validate
|
||||||
|
* the query. Once it is done (which could take recursive lookups, but
|
||||||
|
* in this example no recursive lookups are needed), it returns from the
|
||||||
|
* operate function with finished.
|
||||||
|
*
|
||||||
|
* There is no previous module from the validator module, and the mesh
|
||||||
|
* takes this to mean that the query is finally done. The mesh invokes
|
||||||
|
* callbacks and sends packets to queriers.
|
||||||
|
*
|
||||||
|
* If other modules had been waiting (recursively) on the answer to this
|
||||||
|
* query, then the mesh will tell them about it. It calls the inform_super
|
||||||
|
* routine on all the waiting modules, and once that is done it calls all of
|
||||||
|
* them with the operate() call. During inform_super the query that is done
|
||||||
|
* still exists and information can be copied from it (but the module should
|
||||||
|
* not really re-entry codepoints and services). During the operate call
|
||||||
|
* the modules can use stored state to continue operation with the results.
|
||||||
|
* (network buffers are used to contain the answer packet during the
|
||||||
|
* inform_super phase, but after that the network buffers will be cleared
|
||||||
|
* of their contents so that other tasks can be performed).
|
||||||
|
*
|
||||||
|
* *** Example module calls for recursion
|
||||||
|
*
|
||||||
|
* A module is called in operate, and it decides that it wants to perform
|
||||||
|
* recursion. That is, it wants the full state-machine-list to operate on
|
||||||
|
* a different query. It calls env.attach_sub() to create a new query state.
|
||||||
|
* The routine returns the newly created state, and potentially the module
|
||||||
|
* can edit the module-states for the newly created query (i.e. pass along
|
||||||
|
* some information, like delegation points). The module then suspends,
|
||||||
|
* returns from the operate routine.
|
||||||
|
*
|
||||||
|
* The mesh meanwhile will have the newly created query (or queries) on
|
||||||
|
* a waiting list, and will call operate() on this query (or queries).
|
||||||
|
* It starts again at the start of the module list for them. The query
|
||||||
|
* (or queries) continue to operate their state machines, until they are
|
||||||
|
* done. When they are done the mesh calls inform_super on the module that
|
||||||
|
* wanted the recursion. After that the mesh calls operate() on the module
|
||||||
|
* that wanted to do the recursion, and during this phase the module could,
|
||||||
|
* for example, decide to create more recursions.
|
||||||
|
*
|
||||||
|
* If the module decides it no longer wants the recursive information
|
||||||
|
* it can call detach_subs. Those queries will still run to completion,
|
||||||
|
* potentially filling the cache with information. Inform_super is not
|
||||||
|
* called any more.
|
||||||
|
*
|
||||||
|
* The iterator module will fetch items from the cache, so a recursion
|
||||||
|
* attempt may complete very quickly if the item is in cache. The calling
|
||||||
|
* module has to wait for completion or eventual timeout. A recursive query
|
||||||
|
* that times out returns a servfail rcode (servfail is also returned for
|
||||||
|
* other errors during the lookup).
|
||||||
|
*
|
||||||
|
* Results are passed in the qstate, the rcode member is used to pass
|
||||||
|
* errors without requiring memory allocation, so that the code can continue
|
||||||
|
* in out-of-memory conditions. If the rcode member is 0 (NOERROR) then
|
||||||
|
* the dns_msg entry contains a filled out message. This message may
|
||||||
|
* also contain an rcode that is nonzero, but in this case additional
|
||||||
|
* information (query, additional) can be passed along.
|
||||||
|
*
|
||||||
|
* The rcode and dns_msg are used to pass the result from the the rightmost
|
||||||
|
* module towards the leftmost modules and then towards the user.
|
||||||
|
*
|
||||||
|
* If you want to avoid recursion-cycles where queries need other queries
|
||||||
|
* that need the first one, use detect_cycle() to see if that will happen.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UTIL_MODULE_H
|
#ifndef UTIL_MODULE_H
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue