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_type* 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_type* 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_type* 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_type 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_type* 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_type* 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_type* 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_type* 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_type* store, char* name, char* value); 451 452 /** Print macro variables stored as debug info */ 453 void macro_print_debug(rbtree_type* store); 454 455 /** testbounds self test */ 456 void testbound_selftest(void); 457 458 #endif /* TESTCODE_REPLAY_H */ 459