diff options
Diffstat (limited to 'external/unbound/pythonmod/doc/examples/example5.rst')
-rw-r--r-- | external/unbound/pythonmod/doc/examples/example5.rst | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/external/unbound/pythonmod/doc/examples/example5.rst b/external/unbound/pythonmod/doc/examples/example5.rst new file mode 100644 index 000000000..058fc331e --- /dev/null +++ b/external/unbound/pythonmod/doc/examples/example5.rst @@ -0,0 +1,191 @@ +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 |