]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - pythonmod/doc/examples/example5.rst
import unbound 1.6.0
[FreeBSD/FreeBSD.git] / pythonmod / doc / examples / example5.rst
1 EDNS options
2 ============
3
4 This example shows how to interact with EDNS options.
5
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``.
8
9
10 Key parts
11 ~~~~~~~~~
12
13 This example relies on the following functionalities:
14
15
16 Registering EDNS options
17 ------------------------
18
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:
21
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
26
27 Both values default to ``False``.
28
29 .. code-block:: python
30
31     if not register_edns_option(env, 65001, bypass_cache_stage=True,
32                                 no_aggregation=True):
33         log_info("python: Could not register EDNS option {}".format(65001))
34
35
36 EDNS option lists
37 -----------------
38
39 EDNS option lists can be found in the :class:`module_qstate` class. There are
40 four available lists in total:
41
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
50
51 Each list element has the following members:
52
53 - ``code``: the EDNS option code;
54 - ``data``: the EDNS option data.
55
56
57 Reading an EDNS option list
58 ...........................
59
60 The lists' contents can be accessed in python by their ``_iter`` counterpart as
61 an iterator:
62
63 .. code-block:: python
64
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)))
69
70
71 Writing to an EDNS option list
72 ..............................
73
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``:
77
78 .. code-block:: python
79
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))
84
85 We can also remove an EDNS option code from an EDNS option list.
86
87 .. code-block:: python
88
89     if not edns_opt_list_remove(edns_opt_list, code):
90         log_info("python: Option code {} was not found in the "
91                  "list.".format(code))
92
93 .. note:: All occurences of the EDNS option code will be removed from the list:
94
95
96 Controlling other modules' cache behavior
97 -----------------------------------------
98
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:
102
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
107
108 Both values default to ``0``.
109
110 .. code-block:: python
111
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 "
118                         "or PASS event ")
119                 for o in qstate.edns_opts_front_in_iter:
120                     if o.code == 65001:
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")
126
127                         # Instruct other modules to not store the answer in
128                         # the cache.
129                         qstate.no_cache_store = 1
130                         log_info("python: enabled no_cache_store")
131
132
133 Testing
134 ~~~~~~~
135
136 Run the Unbound server: ::
137
138     root@localhost$ unbound -dv -c ./test-edns.conf
139
140 In case you use your own configuration file, don't forget to enable the Python
141 module::
142
143     module-config: "validator python iterator"
144
145 and use a valid script path::
146
147     python-script: "./examples/edns.py"
148
149 Quering with EDNS option ``65001:0xc001``:
150
151 ::
152
153     root@localhost$ dig @localhost nlnetlabs.nl +ednsopt=65001:c001
154
155     ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost nlnetlabs.nl +ednsopt=65001:c001
156     ; (1 server found)
157     ;; global options: +cmd
158     ;; Got answer:
159     ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33450
160     ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 3
161
162     ;; OPT PSEUDOSECTION:
163     ; EDNS: version: 0, flags:; udp: 4096
164     ; OPT=65001: de ad be ef ("....")
165     ;; QUESTION SECTION:
166     ;nlnetlabs.nl.                  IN      A
167
168     ;; ANSWER SECTION:
169     nlnetlabs.nl.           10200   IN      A       185.49.140.10
170
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.
176
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
180
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
185
186
187 Complete source code
188 ~~~~~~~~~~~~~~~~~~~~
189
190 .. literalinclude:: ../../examples/edns.py
191     :language: python