4 This example shows how to interact with EDNS options.
6 When quering unbound with the EDNS option ``65001`` and data ``0xc001`` we
7 expect an answer with the same EDNS option code and data ``0xdeadbeef``.
13 This example relies on the following functionalities:
16 Registering EDNS options
17 ------------------------
19 By registering EDNS options we can tune unbound's behavior when encountering a
20 query with a known EDNS option. The two available options are:
22 - ``bypass_cache_stage``: If set to ``True`` unbound will not try to answer
23 from cache. Instead execution is passed to the modules
24 - ``no_aggregation``: If set to ``True`` unbound will consider this query
25 unique and will not aggregate it with similar queries
27 Both values default to ``False``.
29 .. code-block:: python
31 if not register_edns_option(env, 65001, bypass_cache_stage=True,
33 log_info("python: Could not register EDNS option {}".format(65001))
39 EDNS option lists can be found in the :class:`module_qstate` class. There are
40 four available lists in total:
42 - :class:`module_qstate.edns_opts_front_in`: options that came from the client
43 side. **Should not** be changed
44 - :class:`module_qstate.edns_opts_back_out`: options that will be sent to the
45 server side. Can be populated by edns literate modules
46 - :class:`module_qstate.edns_opts_back_in`: options that came from the server
47 side. **Should not** be changed
48 - :class:`module_qstate.edns_opts_front_out`: options that will be sent to the
49 client side. Can be populated by edns literate modules
51 Each list element has the following members:
53 - ``code``: the EDNS option code;
54 - ``data``: the EDNS option data.
57 Reading an EDNS option list
58 ...........................
60 The lists' contents can be accessed in python by their ``_iter`` counterpart as
63 .. code-block:: python
65 if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
66 for o in qstate.edns_opts_front_in_iter:
67 log_info("python: Code: {}, Data: '{}'".format(o.code,
68 "".join('{:02x}'.format(x) for x in o.data)))
71 Writing to an EDNS option list
72 ..............................
74 By appending to an EDNS option list we can add new EDNS options. The new
75 element is going to be allocated in :class:`module_qstate.region`. The data
76 **must** be represented with a python ``bytearray``:
78 .. code-block:: python
80 b = bytearray.fromhex("deadbeef")
81 if not edns_opt_list_append(qstate.edns_opts_front_out,
82 o.code, b, qstate.region):
83 log_info("python: Could not append EDNS option {}".format(o.code))
85 We can also remove an EDNS option code from an EDNS option list.
87 .. code-block:: python
89 if not edns_opt_list_remove(edns_opt_list, code):
90 log_info("python: Option code {} was not found in the "
93 .. note:: All occurences of the EDNS option code will be removed from the list:
96 Controlling other modules' cache behavior
97 -----------------------------------------
99 During the modules' operation, some modules may interact with the cache
100 (e.g., iterator). This behavior can be controlled by using the following
101 :class:`module_qstate` flags:
103 - :class:`module_qstate.no_cache_lookup`: Modules *operating after* this module
104 will not lookup the cache for an answer
105 - :class:`module_qstate.no_cache_store`: Modules *operating after* this module
106 will not store the response in the cache
108 Both values default to ``0``.
110 .. code-block:: python
112 def operate(id, event, qstate, qdata):
113 if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
114 # Detect if edns option code 56001 is present from the client side. If
115 # so turn on the flags for cache management.
116 if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
117 log_info("python: searching for edns option code 65001 during NEW "
119 for o in qstate.edns_opts_front_in_iter:
121 log_info("python: found edns option code 65001")
122 # Instruct other modules to not lookup for an
123 # answer in the cache.
124 qstate.no_cache_lookup = 1
125 log_info("python: enabled no_cache_lookup")
127 # Instruct other modules to not store the answer in
129 qstate.no_cache_store = 1
130 log_info("python: enabled no_cache_store")
136 Run the Unbound server: ::
138 root@localhost$ unbound -dv -c ./test-edns.conf
140 In case you use your own configuration file, don't forget to enable the Python
143 module-config: "validator python iterator"
145 and use a valid script path::
147 python-script: "./examples/edns.py"
149 Quering with EDNS option ``65001:0xc001``:
153 root@localhost$ dig @localhost nlnetlabs.nl +ednsopt=65001:c001
155 ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost nlnetlabs.nl +ednsopt=65001:c001
157 ;; global options: +cmd
159 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33450
160 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 3
162 ;; OPT PSEUDOSECTION:
163 ; EDNS: version: 0, flags:; udp: 4096
164 ; OPT=65001: de ad be ef ("....")
169 nlnetlabs.nl. 10200 IN A 185.49.140.10
171 ;; AUTHORITY SECTION:
172 nlnetlabs.nl. 10200 IN NS anyns.pch.net.
173 nlnetlabs.nl. 10200 IN NS ns.nlnetlabs.nl.
174 nlnetlabs.nl. 10200 IN NS ns-ext1.sidn.nl.
175 nlnetlabs.nl. 10200 IN NS sec2.authdns.ripe.net.
177 ;; ADDITIONAL SECTION:
178 ns.nlnetlabs.nl. 10200 IN AAAA 2a04:b900::8:0:0:60
179 ns.nlnetlabs.nl. 10200 IN A 185.49.140.60
181 ;; Query time: 10 msec
182 ;; SERVER: 127.0.0.1#53(127.0.0.1)
183 ;; WHEN: Mon Dec 05 14:50:56 CET 2016
184 ;; MSG SIZE rcvd: 212
190 .. literalinclude:: ../../examples/edns.py