--- /dev/null
+/*
+ * testcode/replay.c - store and use a replay of events for the DNS resolver.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ * Store and use a replay of events for the DNS resolver.
+ * Used to test known scenarios to get known outcomes.
+ */
+
+#include "config.h"
+#include "testcode/replay.h"
+
--- /dev/null
+/*
+ * testcode/replay.h - store and use a replay of events for the DNS resolver.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ * Store and use a replay of events for the DNS resolver.
+ * Used to test known scenarios to get known outcomes.
+ *
+ * <pre>
+ * File format for replay files.
+ *
+ * ; comment line.
+ * And then a number of entries:
+ * RANGE start_time end_time
+ * match_entries
+ * END_RANGE
+ * ; go to the next moment
+ * STEP time_step event_type
+ * ; event_type can be:
+ * o NOTHING - nothing
+ * o QUERY - followed by entry
+ * o CHECK_ANSWER - followed by entry
+ * o CHECK_OUT_QUERY - followed by entry
+ * o REPLY - followed by entry
+ * o TIMEOUT
+ * ; following entry starts on the next line, ENTRY_BEGIN.
+ *
+ *
+ * ; Example file
+ * RANGE 0 100
+ * ENTRY_BEGIN
+ * ; precoded answers to queries.
+ * ENTRY_END
+ * END_RANGE
+ * STEP 0 QUERY
+ * ENTRY_BEGIN
+ * ; query
+ * ENTRY_END
+ * ; a query is sent out to the network by resolver.
+ * ; precoded answer from range is returned.
+ * ; algorithm will do precoded answers immediately, except if
+ * ; the next step specifically checks for that OUT_QUERY.
+ * ; or if none of the precoded answers match.
+ * STEP 1 CHECK_ANSWER
+ * ENTRY_BEGIN
+ * ; what the reply should look like
+ * ENTRY_END
+ * ; successful termination. (if the answer was OK).
+ *
+ * </pre>
+ */
+
+#ifndef TESTCODE_REPLAY_H
+#define TESTCODE_REPLAY_H
+#include "config.h"
+#include "util/netevent.h"
+struct replay_moment;
+struct fake_pending;
+struct replay_answer;
+struct replay_range;
+struct entry;
+
+/**
+ * A replay scenario.
+ */
+struct replay_scenario {
+
+ /** The list of replay moments. Linked list. Time increases in list. */
+ struct replay_moment* mom_first;
+ /** The last element in list of replay moments. */
+ struct replay_moment* mom_last;
+
+ /**
+ * List of matching answers. This is to ease replay scenario
+ * creation. It lists queries (to the network) and what answer
+ * should be returned. The matching answers are valid for a range
+ * of time steps.
+ * So: timestep, parts of query, destination --> answer.
+ */
+ struct replay_range* range_list;
+
+ /**
+ * List of pending queries in order they were sent out. First
+ * one has been sent out most recently. Last one in list is oldest.
+ */
+ struct fake_pending* pending_list;
+
+ /**
+ * List of answers from the matching list, that need to be returned
+ * to the program.
+ */
+ struct replay_answer* answer_list;
+
+ /** callback for incoming queries */
+ comm_point_callback_t* callback_query;
+ /** user argument for incoming query callback */
+ void *cb_arg;
+};
+
+/**
+ * A replay moment.
+ * Basically, it consists of events to a fake select() call.
+ * This is a recording of an event that happens.
+ * And if output is presented, what is done with that.
+ */
+struct replay_moment {
+ /**
+ * The replay time step number. Starts at 0, time is incremented
+ * every time the fake select() is run.
+ */
+ size_t time_step;
+ /** Next replay moment in list of replay moments. */
+ struct replay_moment* mom_next;
+
+ /** what happens this moment? */
+ enum replay_event_type {
+ /** nothing happens, as if this event is not there. */
+ repevt_nothing,
+ /** incoming query */
+ repevt_front_query,
+ /** test fails if reply to query does not match */
+ repevt_front_reply,
+ /** timeout */
+ repevt_timeout,
+ /** reply arrives from the network */
+ repevt_back_reply,
+ /** test fails if query to the network does not match */
+ repevt_back_query,
+ } evt_type;
+
+ /** The sent packet must match this. Incoming events, the data. */
+ struct entry* match;
+
+ /** what pending query should timeout or is answered. or
+ * NULL for last sent query. */
+ ldns_rr* qname;
+};
+
+/**
+ * Pending queries to network, fake replay version.
+ */
+struct fake_pending {
+ /** what is important only that we remember the query, copied here. */
+ ldns_buffer* buffer;
+ /** and to what address this is sent to. */
+ struct sockaddr_storage addr;
+ /** len of addr */
+ socklen_t addrlen;
+ /** The callback function to call */
+ comm_point_callback_t* callback;
+ /** callback user argument */
+ void* cb_arg;
+};
+
+/**
+ * An answer to a back-query, stored so it can be provided as an event.
+ */
+struct replay_answer {
+ /** Next in list */
+ struct replay_answer* next;
+ /** pending question this is an answer to */
+ struct fake_pending* question;
+ /** The answer. */
+ ldns_buffer* buf;
+};
+
+/**
+ * Range of timesteps, and canned replies to matching queries.
+ */
+struct replay_range {
+ /** time range when this is valid. Including start and end step. */
+ size_t start_step;
+ /** end step of time range. */
+ size_t end_step;
+
+ /** Matching list */
+ struct entry* match;
+
+ /** next in list of time ranges. */
+ struct replay_range* next_range;
+};
+
+#endif /* TESTCODE_REPLAY_H */