Skip to content
Snippets Groups Projects
Commit 60fa1b3e authored by Marek Vavruša's avatar Marek Vavruša
Browse files

doc: updated library doc for developers

parent f5323e6c
Branches
Tags
No related merge requests found
doc/resolution.png

93.7 KiB

......@@ -7,8 +7,8 @@ Requirements
* libknot_ 2.0 (Knot DNS high-performance DNS library.)
Library layout
==============
For users
=========
.. contents::
:depth: 1
......@@ -21,19 +21,30 @@ Resolving a name
.. note:: Migrating from ``getaddrinfo``
Using getdns API
----------------
.. _lib-layers:
.. note:: These are not the droids you're looking for, move along.
For developers
==============
.. _lib-layers:
The resolution process starts with the functions in :ref:`resolve.c <lib_api_rplan>`, they are responsible for:
* reacting to state machine state (i.e. calling consume layers if we have an answer ready)
* interacting with the user (i.e. asking caller for I/O, accepting queries)
* fetching assets needed by layers (i.e. zone cut, next best NS address or trust anchor)
These we call as *driver*. The driver is not meant to know *"how"* the query is resolved, but rather *"when"* to execute *"what"*. Typically here you can modify or reorder the resolution plan, or request input from the caller.
.. image:: ../doc/resolution.png
:align: center
On the other side are *layers*. They are responsible for dissecting the packets and informing the driver about the results. For example, a produce layer can generate a sub-request, a consume layer can satisfy an outstanding query or simply log something, but they should **never** alter resolution plan directly, as it would change "current query" for next-in-line layers (appending to the resolution plan is fine). They also must not block, and may not be paused.
.. tip:: Layers are executed asynchronously by the driver. If you need some asset beforehand, you can signalize the driver using returning state or current query flags. For example, setting a flag ``QUERY_AWAIT_CUT`` forces driver to fetch zone cut information before the packet is consumed; setting a ``QUERY_RESOLVED`` flag makes it pop a query after the current set of layers is finished; returning ``FAIL`` state makes it fail current query. The important thing is, these actions happen **after** current set of layers is done.
Writing layers
==============
The resolver :ref:`library <lib_index>` leverages the `processing API`_ from the libknot to separate packet processing code
into layers. In order to keep the core library sane and coverable, there are only two built-in layers:
the :c:func:`iterate_layer`, and the :c:func:`rrcache_layer`.
The resolver :ref:`library <lib_index>` leverages the `processing API`_ from the libknot to separate packet processing code into layers.
*Note* |---| This is only crash-course in the library internals, see the resolver :ref:`library <lib_index>` documentation for the complete overview of the services.
......@@ -55,6 +66,8 @@ resolution context, resolution plan and also the final answer. You're likely to
struct kr_query *query = kr_rplan_current(request->rplan);
}
.. warning:: Never replace or push new queries onto the resolution plan, this is a job of the resolution driver. Single pass through layers expects *current query* to be constant. You can however signalize driver with requests using query flags, like ``QUERY_RESOLVED`` to mark it as resolved.
This is only passive processing of the incoming answer. If you want to change the course of resolution, say satisfy a query from a local cache before the library issues a query to the nameserver, you can use states (see the :ref:`Static hints <mod-hints>` for example).
.. code-block:: c
......@@ -68,7 +81,7 @@ This is only passive processing of the incoming answer. If you want to change th
if (can_satisfy(cur)) {
/* This flag makes the resolver move the query
* to the "resolved" list. */
query->resolved = true;
query->flags |= QUERY_RESOLVED;
return KNOT_STATE_DONE;
}
......@@ -76,8 +89,7 @@ This is only passive processing of the incoming answer. If you want to change th
return ctx->state;
}
It is possible to not only act during the query resolution, but also to view the complete resolution plan afterwards.
This is useful for analysis-type tasks, or *"on-resolution"* hooks.
It is possible to not only act during the query resolution, but also to view the complete resolution plan afterwards. This is useful for analysis-type tasks, or *"per answer"* hooks.
.. code-block:: c
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment