monero/external/unbound/pythonmod/doc/examples/example5.rst
Erik de Castro Lopo a85b5759f3 Upgrade unbound library
These files were pulled from the 1.6.3 release tarball.

This new version builds against OpenSSL version 1.1 which will be
the default in the new Debian Stable which is due to be released
RealSoonNow (tm).
2017-06-17 23:04:00 +10:00

192 lines
6.3 KiB
ReStructuredText

EDNS options
============
This example shows how to interact with EDNS options.
When quering unbound with the EDNS option ``65001`` and data ``0xc001`` we
expect an answer with the same EDNS option code and data ``0xdeadbeef``.
Key parts
~~~~~~~~~
This example relies on the following functionalities:
Registering EDNS options
------------------------
By registering EDNS options we can tune unbound's behavior when encountering a
query with a known EDNS option. The two available options are:
- ``bypass_cache_stage``: If set to ``True`` unbound will not try to answer
from cache. Instead execution is passed to the modules
- ``no_aggregation``: If set to ``True`` unbound will consider this query
unique and will not aggregate it with similar queries
Both values default to ``False``.
.. code-block:: python
if not register_edns_option(env, 65001, bypass_cache_stage=True,
no_aggregation=True):
log_info("python: Could not register EDNS option {}".format(65001))
EDNS option lists
-----------------
EDNS option lists can be found in the :class:`module_qstate` class. There are
four available lists in total:
- :class:`module_qstate.edns_opts_front_in`: options that came from the client
side. **Should not** be changed
- :class:`module_qstate.edns_opts_back_out`: options that will be sent to the
server side. Can be populated by edns literate modules
- :class:`module_qstate.edns_opts_back_in`: options that came from the server
side. **Should not** be changed
- :class:`module_qstate.edns_opts_front_out`: options that will be sent to the
client side. Can be populated by edns literate modules
Each list element has the following members:
- ``code``: the EDNS option code;
- ``data``: the EDNS option data.
Reading an EDNS option list
...........................
The lists' contents can be accessed in python by their ``_iter`` counterpart as
an iterator:
.. code-block:: python
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
for o in qstate.edns_opts_front_in_iter:
log_info("python: Code: {}, Data: '{}'".format(o.code,
"".join('{:02x}'.format(x) for x in o.data)))
Writing to an EDNS option list
..............................
By appending to an EDNS option list we can add new EDNS options. The new
element is going to be allocated in :class:`module_qstate.region`. The data
**must** be represented with a python ``bytearray``:
.. code-block:: python
b = bytearray.fromhex("deadbeef")
if not edns_opt_list_append(qstate.edns_opts_front_out,
o.code, b, qstate.region):
log_info("python: Could not append EDNS option {}".format(o.code))
We can also remove an EDNS option code from an EDNS option list.
.. code-block:: python
if not edns_opt_list_remove(edns_opt_list, code):
log_info("python: Option code {} was not found in the "
"list.".format(code))
.. note:: All occurences of the EDNS option code will be removed from the list:
Controlling other modules' cache behavior
-----------------------------------------
During the modules' operation, some modules may interact with the cache
(e.g., iterator). This behavior can be controlled by using the following
:class:`module_qstate` flags:
- :class:`module_qstate.no_cache_lookup`: Modules *operating after* this module
will not lookup the cache for an answer
- :class:`module_qstate.no_cache_store`: Modules *operating after* this module
will not store the response in the cache
Both values default to ``0``.
.. code-block:: python
def operate(id, event, qstate, qdata):
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
# Detect if edns option code 56001 is present from the client side. If
# so turn on the flags for cache management.
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
log_info("python: searching for edns option code 65001 during NEW "
"or PASS event ")
for o in qstate.edns_opts_front_in_iter:
if o.code == 65001:
log_info("python: found edns option code 65001")
# Instruct other modules to not lookup for an
# answer in the cache.
qstate.no_cache_lookup = 1
log_info("python: enabled no_cache_lookup")
# Instruct other modules to not store the answer in
# the cache.
qstate.no_cache_store = 1
log_info("python: enabled no_cache_store")
Testing
~~~~~~~
Run the Unbound server: ::
root@localhost$ unbound -dv -c ./test-edns.conf
In case you use your own configuration file, don't forget to enable the Python
module::
module-config: "validator python iterator"
and use a valid script path::
python-script: "./examples/edns.py"
Quering with EDNS option ``65001:0xc001``:
::
root@localhost$ dig @localhost nlnetlabs.nl +ednsopt=65001:c001
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost nlnetlabs.nl +ednsopt=65001:c001
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33450
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 3
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; OPT=65001: de ad be ef ("....")
;; QUESTION SECTION:
;nlnetlabs.nl. IN A
;; ANSWER SECTION:
nlnetlabs.nl. 10200 IN A 185.49.140.10
;; AUTHORITY SECTION:
nlnetlabs.nl. 10200 IN NS anyns.pch.net.
nlnetlabs.nl. 10200 IN NS ns.nlnetlabs.nl.
nlnetlabs.nl. 10200 IN NS ns-ext1.sidn.nl.
nlnetlabs.nl. 10200 IN NS sec2.authdns.ripe.net.
;; ADDITIONAL SECTION:
ns.nlnetlabs.nl. 10200 IN AAAA 2a04:b900::8:0:0:60
ns.nlnetlabs.nl. 10200 IN A 185.49.140.60
;; Query time: 10 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 05 14:50:56 CET 2016
;; MSG SIZE rcvd: 212
Complete source code
~~~~~~~~~~~~~~~~~~~~
.. literalinclude:: ../../examples/edns.py
:language: python