]> git.saurik.com Git - apple/network_cmds.git/blob - unbound/testcode/replay.h
network_cmds-596.100.2.tar.gz
[apple/network_cmds.git] / unbound / testcode / replay.h
1 /*
2 * testcode/replay.h - store and use a replay of events for the DNS resolver.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /**
37 * \file
38 * Store and use a replay of events for the DNS resolver.
39 * Used to test known scenarios to get known outcomes.
40 *
41 * <pre>
42 * File format for replay files.
43 *
44 * ; unbound.conf options.
45 * ; ...
46 * ; additional commandline options to pass to unbound
47 * COMMANDLINE cmdline_option
48 * ; autotrust key file contents, also adds auto-trust-anchor-file: "x" to cfg
49 * AUTOTRUST_FILE id
50 * ; contents of that file
51 * AUTOTRUST_END
52 * CONFIG_END
53 * ; comment line.
54 * SCENARIO_BEGIN name_of_scenario
55 * RANGE_BEGIN start_time end_time
56 * ; give ip of the virtual server, it matches any ip if not present.
57 * ADDRESS ip_address
58 * match_entries
59 * RANGE_END
60 * ; more RANGE items.
61 * ; go to the next moment
62 * STEP time_step event_type [ADDRESS ip_address]
63 * ; event_type can be:
64 * o NOTHING - nothing
65 * o QUERY - followed by entry
66 * o CHECK_ANSWER - followed by entry
67 * o CHECK_OUT_QUERY - followed by entry (if copy-id it is also reply).
68 * o REPLY - followed by entry
69 * o TIMEOUT
70 * o TIME_PASSES ELAPSE [seconds] - increase 'now' time counter, can be
71 * a floating point number.
72 * TIME_PASSES EVAL [macro] - expanded for seconds to move time.
73 * o TRAFFIC - like CHECK_ANSWER, causes traffic to flow.
74 * actually the traffic flows before this step is taken.
75 * the step waits for traffic to stop.
76 * o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END.
77 * The file contents is macro expanded before match.
78 * o INFRA_RTT [ip] [dp] [rtt] - update infra cache entry with rtt.
79 * o ERROR
80 * ; following entry starts on the next line, ENTRY_BEGIN.
81 * ; more STEP items
82 * SCENARIO_END
83 *
84 * Calculations, a macro-like system: ${$myvar + 3600}
85 * STEP 10 ASSIGN myvar = 3600
86 * ; ASSIGN event. '=' is syntactic sugar here. 3600 is some expression.
87 * ${..} is macro expanded from its expression. Text substitution.
88 * o $var replaced with its value. var is identifier [azAZ09_]*
89 * o number is that number.
90 * o ${variables and arithmetic }
91 * o +, -, / and *. Note, evaluated left-to-right. Use ${} for brackets.
92 * So again, no precedence rules, so 2+3*4 == ${2+3}*4 = 20.
93 * Do 2+${3*4} to get 24.
94 * o ${function params}
95 * o ${time} is the current time for the simulated unbound.
96 * o ${ctime value} is the text ctime(value), Fri 3 Aug 2009, ...
97 * o ${timeout} is the time until next timeout in comm_timer list.
98 * o ${range lower value upper} checks if lower<=value<=upper
99 * returns value if check succeeds.
100 *
101 * ; Example file
102 * SCENARIO_BEGIN Example scenario
103 * RANGE_BEGIN 0 100
104 * ENTRY_BEGIN
105 * ; precoded answers to queries.
106 * ENTRY_END
107 * END_RANGE
108 * STEP 0 QUERY
109 * ENTRY_BEGIN
110 * ; query
111 * ENTRY_END
112 * ; a query is sent out to the network by resolver.
113 * ; precoded answer from range is returned.
114 * ; algorithm will do precoded answers from RANGE immediately, except if
115 * ; the next step specifically checks for that OUT_QUERY.
116 * ; or if none of the precoded answers match.
117 * STEP 1 CHECK_ANSWER
118 * ENTRY_BEGIN
119 * ; what the reply should look like
120 * ENTRY_END
121 * ; successful termination. (if the answer was OK).
122 * ; also, all answers must have been checked with CHECK_ANSWER.
123 * ; and, no more pending out_queries (that have not been checked).
124 * SCENARIO_END
125 *
126 * </pre>
127 */
128
129 #ifndef TESTCODE_REPLAY_H
130 #define TESTCODE_REPLAY_H
131 #include "util/netevent.h"
132 #include "testcode/testpkts.h"
133 #include "util/rbtree.h"
134 struct replay_answer;
135 struct replay_moment;
136 struct replay_range;
137 struct fake_pending;
138 struct fake_timer;
139 struct replay_var;
140 struct infra_cache;
141 struct sldns_buffer;
142
143 /**
144 * A replay scenario.
145 */
146 struct replay_scenario {
147 /** name of replay scenario. malloced string. */
148 char* title;
149
150 /** The list of replay moments. Linked list. Time increases in list. */
151 struct replay_moment* mom_first;
152 /** The last element in list of replay moments. */
153 struct replay_moment* mom_last;
154
155 /**
156 * List of matching answers. This is to ease replay scenario
157 * creation. It lists queries (to the network) and what answer
158 * should be returned. The matching answers are valid for a range
159 * of time steps.
160 * So: timestep, parts of query, destination --> answer.
161 */
162 struct replay_range* range_list;
163 };
164
165 /**
166 * A replay moment.
167 * Basically, it consists of events to a fake select() call.
168 * This is a recording of an event that happens.
169 * And if output is presented, what is done with that.
170 */
171 struct replay_moment {
172 /**
173 * The replay time step number. Starts at 0, time is incremented
174 * every time the fake select() is run.
175 */
176 int time_step;
177 /** Next replay moment in list of replay moments. */
178 struct replay_moment* mom_next;
179
180 /** what happens this moment? */
181 enum replay_event_type {
182 /** nothing happens, as if this event is not there. */
183 repevt_nothing,
184 /** incoming query */
185 repevt_front_query,
186 /** test fails if reply to query does not match */
187 repevt_front_reply,
188 /** timeout */
189 repevt_timeout,
190 /** time passes */
191 repevt_time_passes,
192 /** reply arrives from the network */
193 repevt_back_reply,
194 /** test fails if query to the network does not match */
195 repevt_back_query,
196 /** check autotrust key file */
197 repevt_autotrust_check,
198 /** an error happens to outbound query */
199 repevt_error,
200 /** assignment to a variable */
201 repevt_assign,
202 /** store infra rtt cache entry: addr and string (int) */
203 repevt_infra_rtt,
204 /** cause traffic to flow */
205 repevt_traffic
206 }
207 /** variable with what is to happen this moment */
208 evt_type;
209
210 /** The sent packet must match this. Incoming events, the data. */
211 struct entry* match;
212
213 /** the amount of time that passes */
214 struct timeval elapse;
215
216 /** address that must be matched, or packet remote host address. */
217 struct sockaddr_storage addr;
218 /** length of addr, if 0, then any address will do */
219 socklen_t addrlen;
220
221 /** macro name, for assign. */
222 char* variable;
223 /** string argument, for assign. */
224 char* string;
225
226 /** the autotrust file id to check */
227 char* autotrust_id;
228 /** file contents to match, one string per line */
229 struct config_strlist* file_content;
230 };
231
232 /**
233 * Range of timesteps, and canned replies to matching queries.
234 */
235 struct replay_range {
236 /** time range when this is valid. Including start and end step. */
237 int start_step;
238 /** end step of time range. */
239 int end_step;
240 /** address of where this range is served. */
241 struct sockaddr_storage addr;
242 /** length of addr, if 0, then any address will do */
243 socklen_t addrlen;
244
245 /** Matching list */
246 struct entry* match;
247
248 /** next in list of time ranges. */
249 struct replay_range* next_range;
250 };
251
252 /**
253 * Replay storage of runtime information.
254 */
255 struct replay_runtime {
256 /**
257 * The scenario
258 */
259 struct replay_scenario* scenario;
260 /**
261 * Current moment.
262 */
263 struct replay_moment* now;
264
265 /**
266 * List of pending queries in order they were sent out. First
267 * one has been sent out most recently. Last one in list is oldest.
268 */
269 struct fake_pending* pending_list;
270
271 /**
272 * List of answers to queries from clients. These need to be checked.
273 */
274 struct replay_answer* answer_list;
275
276 /** last element in answer list. */
277 struct replay_answer* answer_last;
278
279 /** list of fake timer callbacks that are pending */
280 struct fake_timer* timer_list;
281
282 /** callback to call for incoming queries */
283 comm_point_callback_t* callback_query;
284 /** user argument for incoming query callback */
285 void *cb_arg;
286
287 /** ref the infra cache (was passed to outside_network_create) */
288 struct infra_cache* infra;
289
290 /** the current time in seconds */
291 time_t now_secs;
292 /** the current time in microseconds */
293 struct timeval now_tv;
294
295 /** signal handler callback */
296 void (*sig_cb)(int, void*);
297 /** signal handler user arg */
298 void *sig_cb_arg;
299 /** time to exit cleanly */
300 int exit_cleanly;
301
302 /** size of buffers */
303 size_t bufsize;
304
305 /**
306 * Tree of macro values. Of type replay_var
307 */
308 rbtree_t* vars;
309 };
310
311 /**
312 * Pending queries to network, fake replay version.
313 */
314 struct fake_pending {
315 /** what is important only that we remember the query, copied here. */
316 struct sldns_buffer* buffer;
317 /** and to what address this is sent to. */
318 struct sockaddr_storage addr;
319 /** len of addr */
320 socklen_t addrlen;
321 /** zone name, uncompressed wire format (as used when sent) */
322 uint8_t* zone;
323 /** length of zone name */
324 size_t zonelen;
325 /** qtype */
326 int qtype;
327 /** The callback function to call when answer arrives (or timeout) */
328 comm_point_callback_t* callback;
329 /** callback user argument */
330 void* cb_arg;
331 /** original timeout in seconds from 'then' */
332 int timeout;
333
334 /** next in pending list */
335 struct fake_pending* next;
336 /** the buffer parsed into a sldns_pkt */
337 uint8_t* pkt;
338 size_t pkt_len;
339 /** by what transport was the query sent out */
340 enum transport_type transport;
341 /** if this is a serviced query */
342 int serviced;
343 /** the runtime structure this is part of */
344 struct replay_runtime* runtime;
345 };
346
347 /**
348 * An answer that is pending to happen.
349 */
350 struct replay_answer {
351 /** Next in list */
352 struct replay_answer* next;
353 /** reply information */
354 struct comm_reply repinfo;
355 /** the answer preparsed as ldns pkt */
356 uint8_t* pkt;
357 size_t pkt_len;
358 };
359
360 /**
361 * Timers with callbacks, fake replay version.
362 */
363 struct fake_timer {
364 /** next in list */
365 struct fake_timer* next;
366 /** the runtime structure this is part of */
367 struct replay_runtime* runtime;
368 /** the callback to call */
369 void (*cb)(void*);
370 /** the callback user argument */
371 void* cb_arg;
372 /** if timer is enabled */
373 int enabled;
374 /** when the timer expires */
375 struct timeval tv;
376 };
377
378 /**
379 * Replay macro variable. And its value.
380 */
381 struct replay_var {
382 /** rbtree node. Key is this structure. Sorted by name. */
383 rbnode_t node;
384 /** the variable name */
385 char* name;
386 /** the variable value */
387 char* value;
388 };
389
390 /**
391 * Read a replay scenario from the file.
392 * @param in: file to read from.
393 * @param name: name to print in errors.
394 * @param lineno: incremented for every line read.
395 * @return: Scenario. NULL if no scenario read.
396 */
397 struct replay_scenario* replay_scenario_read(FILE* in, const char* name,
398 int* lineno);
399
400 /**
401 * Delete scenario.
402 * @param scen: to delete.
403 */
404 void replay_scenario_delete(struct replay_scenario* scen);
405
406 /** compare two replay_vars */
407 int replay_var_compare(const void* a, const void* b);
408
409 /** get oldest enabled fake timer */
410 struct fake_timer* replay_get_oldest_timer(struct replay_runtime* runtime);
411
412 /**
413 * Create variable storage
414 * @return new or NULL on failure.
415 */
416 rbtree_t* macro_store_create(void);
417
418 /**
419 * Delete variable storage
420 * @param store: the macro storage to free up.
421 */
422 void macro_store_delete(rbtree_t* store);
423
424 /**
425 * Apply macro substitution to string.
426 * @param store: variable store.
427 * @param runtime: the runtime to look up values as needed.
428 * @param text: string to work on.
429 * @return newly malloced string with result.
430 */
431 char* macro_process(rbtree_t* store, struct replay_runtime* runtime,
432 char* text);
433
434 /**
435 * Look up a macro value. Like calling ${$name}.
436 * @param store: variable store
437 * @param name: macro name
438 * @return newly malloced string with result or strdup("") if not found.
439 * or NULL on malloc failure.
440 */
441 char* macro_lookup(rbtree_t* store, char* name);
442
443 /**
444 * Set macro value.
445 * @param store: variable store
446 * @param name: macro name
447 * @param value: text to set it to. Not expanded.
448 * @return false on failure.
449 */
450 int macro_assign(rbtree_t* store, char* name, char* value);
451
452 /** Print macro variables stored as debug info */
453 void macro_print_debug(rbtree_t* store);
454
455 /** testbounds self test */
456 void testbound_selftest(void);
457
458 #endif /* TESTCODE_REPLAY_H */