1Deckard scenario guide
2======================
3.. contents::
4
5On the highest level, Deckard scenario consists of three parts (in this order):
6
7- scenario-specific configuration in the header,
8- declarative description of the simulated network environment,
9- sequence of test steps.
10
11The scenario is stored as ASCII encoded text file with following structure:
12
13.. code-block::
14
15   ; configuration part starts on beginning of the file
16   ; comments start with semicolon
17   CONFIG_END
18
19   SCENARIO_BEGIN       ; SCENARIO block combines declarative description and sequence of steps
20
21
22   ; declarative description of network environment starts here
23   RANGE_BEGIN a b
24   ENTRY_BEGIN
25       ; entries inside RANGE block describe DNS messages
26       ; used as answers from simulated network
27   ENTRY_END
28   RANGE_END
29
30
31   ; sequence of test steps begins here
32   STEP x QUERY         ; this is step number x
33   ENTRY_BEGIN
34       ; ENTRY inside STEP may describe DNS message sent as query
35   ENTRY_END
36
37   STEP y CHECK_ANSWER  ; arbitrary number of steps is allowed
38   ENTRY_BEGIN
39       ; also, ENTRY inside STEP may describe DNS message with expected answer
40   ENTRY_END
41   SCENARIO_END
42
43The scenario is processed as follows:
44
45- Deckard parses configuration block and generates configuration files for binaries under test
46- binaries are executed in an isolated network environment
47- Deckard walks through all ``STEP`` blocks and sends queries to the binary under test, and checks answers it receives
48- when a binary attempts to contact another server, Deckard intercepts the communication and replies with scripted answer as defined in ``RANGE`` blocks
49
50To better understand this structure, we will walk-through from sequential steps through declarative description up to scenario-specific configuration.
51
52Scenario
53--------
54Scenario part starts with ``SCENARIO_BEGIN`` and ends with ``SCENARIO_END`` statements, which are present after ``CONFIG_END`` keyword. ``SCENARIO_BEGIN`` keyword must be followed by scenario description:
55
56.. code-block::
57
58    SCENARIO_BEGIN Test basic query minimization www.example.com.
59    ...
60    SCENARIO_END
61
62
63
64Test steps (``STEP``)
65---------------------
66One ``STEP`` describes one action during scenario execution. It might be action like send next query to binary under test, send reply to binary under test, change faked system time, or check the last answer. Sequence of two steps might look like this:
67
68.. code-block::
69
70   STEP 1 QUERY          ; send query specified in the following ENTRY to the binary
71   ENTRY_BEGIN           ; ENTRY defines content of DNS message
72   REPLY RD
73   SECTION QUESTION
74   www.example.com. IN A
75   ENTRY_END
76
77   STEP 10 CHECK_ANSWER  ; check that answer to the previous query matches following ENTRY
78   ENTRY_BEGIN
79   MATCH all             ; MATCH specifies what fields in answer have to match the ENTRY
80   REPLY QR RD RA NOERROR
81   SECTION QUESTION
82   www.example.com. IN A
83   SECTION ANSWER
84   www.example.com. IN CNAME       www.next.com.
85   www.next.com. IN A 10.20.30.40
86   SECTION AUTHORITY
87   SECTION ADDITIONAL
88   ENTRY_END
89
90
91Most important parts of a step are:
92
93- id - number specifying order in which steps are executed, e.g. ``1`` or ``10``
94- type - action to execute, e.g. ``QUERY`` or ``CHECK_ANSWER``
95- entry - DNS message content, while meaning of the message depends on the step *type*
96
97One ``STEP`` block starts with ``STEP`` keyword and continues until one of {``STEP``,
98``RANGE``, ``END_SCENARIO``} keywords is found.
99
100Format
101^^^^^^
102
103.. code-block::
104
105   STEP id type [additional data]
106
107- id - step identifier, a positive integer value; all steps must have
108  different id's. This value used within RANGE block, see above.
109- type - step type; can be ``QUERY`` | ``REPLY`` | ``CHECK_ANSWER`` | ``TIME_PASSES ELAPSE`` *seconds*
110
111  - QUERY - send query defined by associated ``ENTRY`` to binary under test
112  - CHECK_ANSWER - check if last received answer matches associated ``ENTRY``
113  - TIME_PASSES ELAPSE - move faked system time for binary under test by number of *seconds* to future
114  - REPLY - *use of this type is discouraged*; it defines one-shot reply to query from binary under test
115
116.. warning::
117    - ``REPLY`` type is useful only if you know exact order of queries sent *by the binary under test*
118    - steps of this type are used only when no matching ``RANGE`` datablock exists
119    - priority of ``REPLY`` type is going to change in future
120
121
122.. _entry:
123
124DNS messages (normal ``ENTRY``)
125-------------------------------
126One ``ENTRY`` describes one DNS message plus additional metadata, depending on intended use of the entry. There are three possible uses of entry which require little bit different entry format. An entry might define:
127
128#. *query message* to be sent in ``STEP QUERY``
129#. *expected message* to be compared with a message received from binary in ``STEP CHECK_ANSWER``
130#. *answer template message* to be used for simulating answers from network in ``RANGE`` block
131
132Particular use of data in an ``ENTRY`` depends on context and is different
133for ``STEP`` types and ``RANGE`` blocks, see details below.
134
135In any case, entry starts with ``ENTRY_BEGIN`` and ends with ``ENTRY_END`` keywords and share ``REPLY`` and ``SECTION`` definitions.
136Some fields in DNS messages have default values which can be overriden by explicit specification.
137
138Format of query messages (for ``STEP QUERY``)
139^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
140``STEP QUERY`` requires a DNS message which will be sent by Deckard to the binary under test. Structure of the entry is:
141
142.. code-block::
143
144    STEP <n> QUERY
145    ENTRY_BEGIN
146    REPLY <OPCODE flags>    ; REPLY is a bad keyword name, OPCODE and flags will be sent out!
147    SECTION QUESTION        ; it is possible to replace QUESTION section or omit it
148    <name> <class> <type>   ; to simulate weird queries
149    ENTRY_END
150
151The message will be assigned a random message ID, converted into DNS wire format, and sent to the binary under test.
152
153.. warning:: The keyword ``REPLY`` in fact defines value of flags in the outgoing message. The confusing name is here for compatibility with the original ``testbound``.
154
155
156Format of expected messages (for ``STEP CHECK_ANSWER``)
157^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
158``STEP CHECK_ANSWER`` requires a DNS message which will be compared with a reply received from the binary under test. Structure of the entry describing the expected message is:
159
160.. code-block::
161
162    ENTRY_BEGIN
163    MATCH <match element list>  ; MATCH elements define what message fields will be compared
164    REPLY <OPCODE RCODE flags>  ; REPLY field here defines expected OPCODE, RCODE as well as flags!
165    SECTION QUESTION
166    <name> <class> <type>       ; to simulate weird queries
167    SECTION <type2>
168    <RR sets>
169    ENTRY_END
170
171Deckard will compare messages according to *<match element list>*. Any mismatch between *received* message and the *expected* message (specified by the entry) will result in test failure. (See chapter `entry matching`_.)
172
173
174Format of answer templates (for ``RANGE``)
175^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
176Entries in ``RANGE`` blocks are used to answer queries *from binaries under test*. E.g. if a DNS resolver under test sends query ``. IN NS`` to a simulated server, Deckard will use matching entry associated with the simulated server for reply. Entry used for answer is selected using the same `entry matching`_ logic as with ``STEP CHECK_ANSWER``. The difference is that entry is automatically modified before sending out the answer. These modifications are specified by ``ADJUST`` and ``REPLY`` keywords. It's also possible to not send any reply using the ``ADJUST do_not_answer`` option. See chapters `entry adjusting`_ and `entry flags`_.
177
178.. code-block::
179
180    ENTRY_BEGIN
181    MATCH <match element list>    ; all MATCH elements must match before using this answer template
182    ADJUST <adjust element list>  ; ADJUST fields will be modified before answering
183    REPLY <OPCODE RCODE flags>    ; OPCODE, RCODE, and flags to be set in the outgoing answer
184    SECTION <type1>
185    <RR sets>
186    SECTION <type2>
187    <RR sets>
188    ENTRY_END
189
190
191.. _`entry matching`:
192
193Entry matching
194^^^^^^^^^^^^^^
195Entries present in Deckard scenario define values *expected* in DNS messages. The *expected* values are compared with values in messages *received* from the network. Entry matches only if all specified elements match.
196
197.. code-block::
198
199   MATCH <match element list>
200
201*<match element list>* is a space-separated list of elements in *expected* and *received* messages to be compared. Supported elements are:
202
203============ =========================================================================================
204element      DNS message fields and additional rules
205============ =========================================================================================
206opcode       ``OPCODE`` as `defined in IANA registry <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5>`_
207
208             - *expected* message ``OPCODE`` is defined by ``REPLY`` keyword
209
210qtype        RR type in question section [qmatch]_
211qname        name in question section (case insensitive) [qmatch]_
212qcase        name in question section (case sensitive) [qmatch]_
213subdomain    name in question section of the *received* message is a subdomain of the name in *expected* question section
214             (case insensitive, exact match accepted) [qmatch]_
215flags        all `defined flags <https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-12>`_
216             in message header: ``QR AA TC RD RA AD CD``
217
218             - it does not match on ``DO`` flag which resides in EDNS header flags
219             - *expected* message flags are defined by ``REPLY`` keyword
220
221rcode        extended response code (``RCODE`` value
222             `combined from message header and EDNS header <https://tools.ietf.org/html/rfc6891#section-6.1.3>`_)
223
224             - *expected* message ``RCODE`` is defined by ``REPLY`` keyword
225
226question     equivalent to ``qtype qname``
227answer       whole ANSWER section [sectmatch]_
228authority    whole AUTHORITY section [sectmatch]_
229additional   whole ADDITIONAL section [sectmatch]_
230edns         EDNS `version <https://tools.ietf.org/html/rfc6891#section-6.1.3>`_ and
231             EDNS `payload <https://tools.ietf.org/html/rfc6891#section-6.1.2>`_ size
232nsid         `NSID <https://tools.ietf.org/html/rfc5001>`_ presence and value
233all          equivalent to ``opcode qtype qname flags rcode answer authority additional``
234============ =========================================================================================
235
236.. [qmatch] *Expected* values are defined by QUESTION section in the entry. If the *expected* QUESTION section is empty, the conditions is ignored. Only values from the first (qname, qclass, qtype) tuple are checked. Question matching is case insensitive (except for ``qcase``).
237
238.. [sectmatch] Number of records must match. Owner names are case-insensitive and TTL is ignored. RR data are compared according to type-specific rules. Each RR present in the *expected* message must be present in the *received* message and vice versa.
239
240
241.. _`entry adjusting`:
242
243Entry adjusting
244^^^^^^^^^^^^^^^
245.. code-block::
246
247   ADJUST <adjust element list>
248
249An entry used as a template to prepare an answer to an incoming query might be preprocessed.
250Adjust element list defines what fields will be modified:
251
252============= ===========================================================================================
253element       modification to the DNS message
254============= ===========================================================================================
255copy_id       query id + query domain name will be copied from incoming message [copy_id_bug]_
256copy_query    whole question section will be copied from incoming message
257raw_id        query id will be copied into the first two bytes of RAW answer
258do_not_answer no response will be sent at all
259============= ===========================================================================================
260
261.. [copy_id_bug] https://gitlab.labs.nic.cz/knot/deckard/issues/9
262
263
264.. _`entry flags`:
265
266Entry flags
267^^^^^^^^^^^
268.. code-block::
269
270  REPLY <RCODE flags>
271
272*<RCODE flags>* is space-separated RCODE and list of flags in the entry. Usage of these flags depend on entry context.
273
274Supported values:
275
276  - NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMP, REFUSED, YXDOMAIN, YXRRSET, NXRRSET, NOTAUTH, NOTZONE, BADVERS - standard rcodes
277  - QR, AA, TC, RD, RA, AD, CD - i.e. standard dns flags
278  - DO - enable 'DNSSEC desired' flag
279
280.. warning:: The keyword ``REPLY`` has different meaning depending on the ``ENTRY`` context.
281
282
283Entry RR sections
284^^^^^^^^^^^^^^^^^
285An entry might specify content of DNS message sections QUESTION, ANSWER, AUTHORITY, and ADDITIONAL. Syntax is of resource records is the same as in zone file. Format:
286
287.. code-block::
288
289   SECTION QUESTION
290   <owner name> [class] <RR type>                  ; QUESTION is special
291   SECTION <ANSWER/AUTHORITY/ADDITIONAL>
292   <owner name> [TTL] [class] <RR type> <RR data>  ; same as in zone file
293   ...
294   <owner name> [TTL] [class] <RR type> <RR data>
295
296Example:
297
298.. code-block::
299
300   SECTION QUESTION
301   www.example.com.	IN A
302   SECTION ANSWER
303   www.example.com.	IN A	10.20.30.40
304   SECTION AUTHORITY
305   example.com.	IN NS	ns.example.com.
306   SECTION ADDITIONAL
307   ns.example.com.	IN A	1.2.3.4
308
309
310Default values for DNS messages
311^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
312========== ===========================================================================================
313feature    default value
314========== ===========================================================================================
315EDNS       version 0 with buffer size 4096 B
316REPLY      QUERY, NOERROR
317========== ===========================================================================================
318
319
320Entry with RAW data
321^^^^^^^^^^^^^^^^^^^
322An entry might have special section named ``RAW``. This section is used only for sending raw,
323potentially invalid DNS messages. The section contains a single-line data interpreted as hexadecimal string.
324Data decoded from this string will be sent to binary under test without any changes.
325
326Deckard does not expect any answer to RAW queries, so ``STEP CHECK_ANSWER`` is not needed.
327Main intent of this behavior is to check if binary under test is
328able to process valid queries after getting series badly formed packets.
329
330It is also possible to use ``RAW`` in conjuction with ``SECTION`` for the
331purpose of responding with raw data to a query that matches the ``SECTION``.
332It's possible to modify raw data to use query's ID by using ``ADJUST raw_id``.
333
334One ``ENTRY`` can contain only one ``RAW`` section.
335
336Example
337
338.. code-block::
339
340   ENTRY_BEGIN
341   RAW
342   b5c9ca3d50104320f4120000000000000000
343   ENTRY_END
344
345
346
347Mock answers (``RANGE``)
348------------------------
349When Deckard receives a query *from binary under test*, it searches for mock answers.
350A set of mock answers for particular set of IP addresses and ID range is described using ``RANGE``
351block starting with ``RANGE_BEGIN`` keyword. The ``RANGE`` contains mock DNS messages represented
352as ENTRY_ blocks which specify `entry matching`_ conditions along with `entry adjusting`_ actions and `entry flags`_ specification.
353
354Format:
355
356.. code-block::
357
358   ; comment before the range, e.g. K.ROOT-SERVERS.NET.
359   RANGE_BEGIN 0 100              ; this RANGE is valid for STEP IDs <0, 100>
360           ADDRESS 193.0.14.129   ; IP address simulated by this range
361           ;ADDRESS 192.0.2.222   ; multiple IP addresses are allowed
362
363   ENTRY_BEGIN                    ; first ENTRY in this range
364   MATCH opcode qtype qname       ; use this entry only if all these match the query
365   ADJUST copy_id                 ; adjust message ID before senting the answer
366   REPLY QR NOERROR               ; answer with RCODE NOERROR and QR flag set
367   SECTION QUESTION
368   . IN NS                        ; MATCH qname qtype are compared with this value
369   SECTION ANSWER                 ; all this will be copied verbatim to the answer
370   . IN NS K.ROOT-SERVERS.NET.
371   SECTION ADDITIONAL
372   K.ROOT-SERVERS.NET.     IN      A       193.0.14.129
373   ENTRY_END
374
375   ENTRY_BEGIN                    ; second ENTRY in this range
376   ...
377   ENTRY_END
378
379   RANGE_END
380
381When Deckard receives a query *from binary under test*, it searches for an eligible range. When an eligible range is found, it searches inside the range to find a mock answer. In detail, it works like this:
382
383#. Deckard searches for an eligible ``RANGE`` block. Following two conditions must be fulfilled:
384
385   - current ``STEP ID`` is inside ID range specified by ``RANGE_BEGIN`` keyword.
386   - target IP address of the query is in set of IP addresses specified using ``ADDRESS`` keywords
387
388#. If an eligible range is found, Deckard examines all entries in the range and evaluate all ``MATCH`` conditions associated with entries.
389#. An entry where all MATCH conditions are fulfilled is used as template for the mock answer. (See `entry matching`_.)
390#. Mock answer is modified according to ``ADJUST`` and ``REPLY`` keywords. (See `entry adjusting`_ actions and `entry flags`_ specification.)
391#. The modified answer message is sent to the binary under test.
392
393Valid scenario must specify answers for all queries generated by the binary under test. The test will fail if no answer is found in the eligible range or if no eligible range is defined.
394
395.. note:: Behavior of the binary under test, including queries it generates, depends on its configuration. For example enabling or disabling query name minimization will change minimal set of queries which a test scenario has to describe using ``RANGE`` blocks.
396
397.. tip:: It is recommended to construct scenarios that support multiple configurations and possibly software implementations. This leads to higher number of entries in ``RANGE`` blocks but provides robustness against changes in particular implementation. E.g. a scenario for DNS resolver testing can be developed using multiple DNS resolver implementations and combine entries for all of them inside single scenario. With this approach a small change in a resolver implementation will likely not require further changes to the scenario.
398
399
400Configuration (``CONFIG_END``)
401------------------------------
402Configuration block affects behavior of the binary under test. Deckard transforms configuration block into configuration for the binary under test.
403
404Format is list of "key: value" pairs, one pair per line. There is no explicit start keyword, configuration block starts immediately at scenario file begin and ends with keyword ``CONFIG_END``.
405
406.. code-block::
407
408   ; config options
409           query-minimization: on
410           stub-addr: 193.0.14.129 	; K.ROOT-SERVERS.NET.
411           trust-anchor: ". 3600 IN DS 10000 13 4 ABCDEF0123456789"
412           val-override-date: "1442323400"
413   CONFIG_END
414
415========================== ======= =====================================================================
416config option              default meaning
417========================== ======= =====================================================================
418do-not-query-localhost     on      on = queries cannot be sent to 127.0.0.1/8 or ::1/128 addresses
419domain-insecure            (none)  domain name specifying DNS sub-tree with explicitly disabled DNSSEC validation
420force-ipv6                 off     use a IPv6 address as ``stub-addr``
421harden-glue                on      additional checks on glue addresses
422query-minimization         on      RFC 7816 query algorithm enabled; default inherited from QMIN environment variable
423stub-addr                  (none)  IP address for resolver priming queries (RFC 8109)
424trust-anchor               (none)  owner name with its DS records (this option can be repeated multiple times)
425val-override-date          (none)  system time reported to binary under the test; format ``YYYYMMDDHHMMSS``, so ``20120420235959`` means ``Fri Apr 20 23:59:59 2012``
426val-override-timestamp     (none)  system time reported to binary under the test: format POSIX timestamp
427========================== ======= =====================================================================
428
429Examples
430--------
431See `scenatio example <scenario_example.rst>`_. The example there is a bit terse but still valid.
432