1/*
2 * testcode/fake_event.c - fake event handling that replays existing scenario.
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 * Event service that replays a scenario.
39 * This implements the same exported symbols as the files:
40 * util/netevent.c
41 * services/listen_dnsport.c
42 * services/outside_network.c
43 * But these do not actually access the network or events, instead
44 * the scenario is played.
45 */
46
47#include "config.h"
48#include "testcode/fake_event.h"
49#include "util/netevent.h"
50#include "util/net_help.h"
51#include "util/data/msgparse.h"
52#include "util/data/msgreply.h"
53#include "util/data/msgencode.h"
54#include "util/data/dname.h"
55#include "util/edns.h"
56#include "util/config_file.h"
57#include "services/listen_dnsport.h"
58#include "services/outside_network.h"
59#include "services/cache/infra.h"
60#include "testcode/replay.h"
61#include "testcode/testpkts.h"
62#include "util/log.h"
63#include "util/fptr_wlist.h"
64#include "sldns/sbuffer.h"
65#include "sldns/wire2str.h"
66#include "sldns/str2wire.h"
67#include <signal.h>
68struct worker;
69struct daemon_remote;
70
71/** unique code to check that fake_commpoint is that structure */
72#define FAKE_COMMPOINT_TYPECODE 97347923
73/** fake commpoint, stores information */
74struct fake_commpoint {
75	/** typecode */
76	int typecode;
77	/** if this is a udp outgoing type of commpoint */
78	int type_udp_out;
79	/** if this is a tcp outgoing type of commpoint */
80	int type_tcp_out;
81	/** if this is a http outgoing type of commpoint. */
82	int type_http_out;
83
84	/** the callback, stored for usage */
85	comm_point_callback_type* cb;
86	/** the callback userarg, stored for usage */
87	void* cb_arg;
88	/** runtime ptr */
89	struct replay_runtime* runtime;
90	/** the pending entry for this commpoint (if any) */
91	struct fake_pending* pending;
92};
93
94/** Global variable: the scenario. Saved here for when event_init is done. */
95static struct replay_scenario* saved_scenario = NULL;
96
97/** add timers and the values do not overflow or become negative */
98static void
99timeval_add(struct timeval* d, const struct timeval* add)
100{
101#ifndef S_SPLINT_S
102	d->tv_sec += add->tv_sec;
103	d->tv_usec += add->tv_usec;
104	if(d->tv_usec >= 1000000) {
105		d->tv_usec -= 1000000;
106		d->tv_sec++;
107	}
108#endif
109}
110
111void
112fake_temp_file(const char* adj, const char* id, char* buf, size_t len)
113{
114#ifdef USE_WINSOCK
115	snprintf(buf, len, "testbound_%u%s%s.tmp",
116		(unsigned)getpid(), adj, id);
117#else
118	snprintf(buf, len, "/tmp/testbound_%u%s%s.tmp",
119		(unsigned)getpid(), adj, id);
120#endif
121}
122
123void
124fake_event_init(struct replay_scenario* scen)
125{
126	saved_scenario = scen;
127}
128
129void
130fake_event_cleanup(void)
131{
132	replay_scenario_delete(saved_scenario);
133	saved_scenario = NULL;
134}
135
136/** helper function that logs a sldns_pkt packet to logfile */
137static void
138log_pkt(const char* desc, uint8_t* pkt, size_t len)
139{
140	char* str = sldns_wire2str_pkt(pkt, len);
141	if(!str)
142		fatal_exit("%s: (failed out of memory wire2str_pkt)", desc);
143	else {
144		log_info("%s%s", desc, str);
145		free(str);
146	}
147}
148
149/**
150 * Returns a string describing the event type.
151 */
152static const char*
153repevt_string(enum replay_event_type t)
154{
155	switch(t) {
156	case repevt_nothing:	 return "NOTHING";
157	case repevt_front_query: return "QUERY";
158	case repevt_front_reply: return "CHECK_ANSWER";
159	case repevt_timeout:	 return "TIMEOUT";
160	case repevt_time_passes: return "TIME_PASSES";
161	case repevt_back_reply:  return "REPLY";
162	case repevt_back_query:  return "CHECK_OUT_QUERY";
163	case repevt_autotrust_check: return "CHECK_AUTOTRUST";
164	case repevt_tempfile_check: return "CHECK_TEMPFILE";
165	case repevt_error:	 return "ERROR";
166	case repevt_assign:	 return "ASSIGN";
167	case repevt_traffic:	 return "TRAFFIC";
168	case repevt_infra_rtt:	 return "INFRA_RTT";
169	default:		 return "UNKNOWN";
170	}
171}
172
173/** delete a fake pending */
174static void
175delete_fake_pending(struct fake_pending* pend)
176{
177	if(!pend)
178		return;
179	free(pend->zone);
180	sldns_buffer_free(pend->buffer);
181	free(pend->pkt);
182	free(pend);
183}
184
185/** delete a replay answer */
186static void
187delete_replay_answer(struct replay_answer* a)
188{
189	if(!a)
190		return;
191	if(a->repinfo.c) {
192		sldns_buffer_free(a->repinfo.c->buffer);
193		free(a->repinfo.c);
194	}
195	free(a->pkt);
196	free(a);
197}
198
199/**
200 * return: true if pending query matches the now event.
201 */
202static int
203pending_matches_current(struct replay_runtime* runtime,
204	struct entry** entry, struct fake_pending **pend)
205{
206	struct fake_pending* p;
207	struct entry* e;
208	if(!runtime->now || runtime->now->evt_type != repevt_back_query
209		|| !runtime->pending_list)
210		return 0;
211	/* see if any of the pending queries matches */
212	for(p = runtime->pending_list; p; p = p->next) {
213		if(runtime->now->addrlen != 0 &&
214			sockaddr_cmp(&p->addr, p->addrlen, &runtime->now->addr,
215			runtime->now->addrlen) != 0)
216			continue;
217		if((e=find_match(runtime->now->match, p->pkt, p->pkt_len,
218			p->transport))) {
219			*entry = e;
220			*pend = p;
221			return 1;
222		}
223	}
224	return 0;
225}
226
227/**
228 * Find the range that matches this pending message.
229 * @param runtime: runtime with current moment, and range list.
230 * @param entry: returns the pointer to entry that matches.
231 * @param pend: the pending that the entry must match.
232 * @return: true if a match is found.
233 */
234static int
235pending_find_match(struct replay_runtime* runtime, struct entry** entry,
236	struct fake_pending* pend)
237{
238	int timenow = runtime->now->time_step;
239	struct replay_range* p = runtime->scenario->range_list;
240	while(p) {
241		if(p->start_step <= timenow && timenow <= p->end_step &&
242		  (p->addrlen == 0 || sockaddr_cmp(&p->addr, p->addrlen,
243		  	&pend->addr, pend->addrlen) == 0) &&
244		  (*entry = find_match(p->match, pend->pkt, pend->pkt_len,
245		 	 pend->transport))) {
246			log_info("matched query time %d in range [%d, %d] "
247				"with entry line %d", timenow,
248				p->start_step, p->end_step, (*entry)->lineno);
249			if(p->addrlen != 0)
250				log_addr(0, "matched ip", &p->addr, p->addrlen);
251			log_pkt("matched pkt: ",
252				(*entry)->reply_list->reply_pkt,
253				(*entry)->reply_list->reply_len);
254			return 1;
255		}
256		p = p->next_range;
257	}
258	return 0;
259}
260
261/**
262 * See if outgoing pending query matches an entry.
263 * @param runtime: runtime.
264 * @param entry: if true, the entry that matches is returned.
265 * @param pend: if true, the outgoing message that matches is returned.
266 * @return: true if pending query matches the now event.
267 */
268static int
269pending_matches_range(struct replay_runtime* runtime,
270	struct entry** entry, struct fake_pending** pend)
271{
272	struct fake_pending* p = runtime->pending_list;
273	/* slow, O(N*N), but it works as advertised with weird matching */
274	while(p) {
275		if(p->tcp_pkt_counter != 0) {
276			/* continue tcp transfer */
277			*pend = p;
278			return 1;
279		}
280		if(pending_find_match(runtime, entry, p)) {
281			*pend = p;
282			return 1;
283		}
284		p = p->next;
285	}
286	return 0;
287}
288
289/**
290 * Remove the item from the pending list.
291 */
292static void
293pending_list_delete(struct replay_runtime* runtime, struct fake_pending* pend)
294{
295	struct fake_pending** prev = &runtime->pending_list;
296	struct fake_pending* p = runtime->pending_list;
297
298	while(p) {
299		if(p == pend) {
300			*prev = p->next;
301			delete_fake_pending(pend);
302			return;
303		}
304
305		prev = &p->next;
306		p = p->next;
307	}
308}
309
310/** number of replies in entry */
311static int
312count_reply_packets(struct entry* entry)
313{
314	int count = 0;
315	struct reply_packet* reppkt = entry->reply_list;
316	while(reppkt) {
317		count++;
318		reppkt = reppkt->next;
319	}
320	return count;
321}
322
323/**
324 * Fill buffer with reply from the entry.
325 */
326static void
327fill_buffer_with_reply(sldns_buffer* buffer, struct entry* entry, uint8_t* q,
328	size_t qlen, int tcp_pkt_counter)
329{
330	struct reply_packet* reppkt;
331	uint8_t* c;
332	size_t clen;
333	log_assert(entry && entry->reply_list);
334	sldns_buffer_clear(buffer);
335	reppkt = entry->reply_list;
336	if(tcp_pkt_counter > 0) {
337		int i = tcp_pkt_counter;
338		while(reppkt && i--)
339			reppkt = reppkt->next;
340		if(!reppkt) fatal_exit("extra packet read from TCP stream but none is available");
341		log_pkt("extra_packet ", reppkt->reply_pkt, reppkt->reply_len);
342	}
343	if(reppkt->reply_from_hex) {
344		c = sldns_buffer_begin(reppkt->reply_from_hex);
345		clen = sldns_buffer_limit(reppkt->reply_from_hex);
346		if(!c) fatal_exit("out of memory");
347	} else {
348		c = reppkt->reply_pkt;
349		clen = reppkt->reply_len;
350	}
351	if(c) {
352		if(q) adjust_packet(entry, &c, &clen, q, qlen);
353		sldns_buffer_write(buffer, c, clen);
354		if(q) free(c);
355	}
356	sldns_buffer_flip(buffer);
357}
358
359/**
360 * Perform range entry on pending message.
361 * @param runtime: runtime buffer size preference.
362 * @param entry: entry that codes for the reply to do.
363 * @param pend: pending query that is answered, callback called.
364 */
365static void
366answer_callback_from_entry(struct replay_runtime* runtime,
367        struct entry* entry, struct fake_pending* pend)
368{
369	struct comm_point c;
370	struct comm_reply repinfo;
371	void* cb_arg = pend->cb_arg;
372	comm_point_callback_type* cb = pend->callback;
373
374	memset(&c, 0, sizeof(c));
375	c.fd = -1;
376	c.buffer = sldns_buffer_new(runtime->bufsize);
377	c.type = comm_udp;
378	if(pend->transport == transport_tcp) {
379		c.type = comm_tcp;
380		c.tcp_timeout_msec = 30000;
381		c.tcp_keepalive = runtime->tcp_seen_keepalive;
382	}
383	fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len,
384		pend->tcp_pkt_counter);
385	repinfo.c = &c;
386	repinfo.addrlen = pend->addrlen;
387	memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
388	if(!pend->serviced) {
389		if(entry && entry->reply_list->next &&
390			pend->tcp_pkt_counter < count_reply_packets(entry)) {
391			/* go to next packet next time */
392			pend->tcp_pkt_counter++;
393		} else {
394			pending_list_delete(runtime, pend);
395		}
396	}
397	if((*cb)(&c, cb_arg, NETEVENT_NOERROR, &repinfo)) {
398		fatal_exit("testbound: unexpected: callback returned 1");
399	}
400	sldns_buffer_free(c.buffer);
401}
402
403/** Check the now moment answer check event */
404static void
405answer_check_it(struct replay_runtime* runtime)
406{
407	struct replay_answer* ans = runtime->answer_list,
408		*prev = NULL;
409	log_assert(runtime && runtime->now &&
410		runtime->now->evt_type == repevt_front_reply);
411	while(ans) {
412		enum transport_type tr = transport_tcp;
413		if(ans->repinfo.c->type == comm_udp)
414			tr = transport_udp;
415		if((runtime->now->addrlen == 0 || sockaddr_cmp(
416			&runtime->now->addr, runtime->now->addrlen,
417			&ans->repinfo.addr, ans->repinfo.addrlen) == 0) &&
418			find_match(runtime->now->match, ans->pkt,
419				ans->pkt_len, tr)) {
420			log_info("testbound matched event entry from line %d",
421				runtime->now->match->lineno);
422			log_info("testbound: do STEP %d %s",
423				runtime->now->time_step,
424				repevt_string(runtime->now->evt_type));
425			if(prev)
426				prev->next = ans->next;
427			else 	runtime->answer_list = ans->next;
428			if(!ans->next)
429				runtime->answer_last = prev;
430			if(ans->repinfo.c->tcp_keepalive)
431				runtime->tcp_seen_keepalive = 1;
432			delete_replay_answer(ans);
433			return;
434		} else {
435			prev = ans;
436			ans = ans->next;
437		}
438	}
439	log_info("testbound: do STEP %d %s", runtime->now->time_step,
440		repevt_string(runtime->now->evt_type));
441	fatal_exit("testbound: not matched");
442}
443
444/**
445 * Create commpoint (as return address) for a fake incoming query.
446 */
447static void
448fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
449{
450	struct comm_reply repinfo;
451	memset(&repinfo, 0, sizeof(repinfo));
452	repinfo.c = (struct comm_point*)calloc(1, sizeof(struct comm_point));
453	repinfo.addrlen = (socklen_t)sizeof(struct sockaddr_in);
454	if(todo->addrlen != 0) {
455		repinfo.addrlen = todo->addrlen;
456		memcpy(&repinfo.addr, &todo->addr, todo->addrlen);
457	}
458	repinfo.c->fd = -1;
459	repinfo.c->ev = (struct internal_event*)runtime;
460	repinfo.c->buffer = sldns_buffer_new(runtime->bufsize);
461	if(todo->match->match_transport == transport_tcp) {
462		repinfo.c->type = comm_tcp;
463		repinfo.c->tcp_timeout_msec = 30000;
464		repinfo.c->tcp_keepalive = runtime->tcp_seen_keepalive;
465	} else
466		repinfo.c->type = comm_udp;
467	fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0);
468	log_info("testbound: incoming QUERY");
469	log_pkt("query pkt", todo->match->reply_list->reply_pkt,
470		todo->match->reply_list->reply_len);
471	/* call the callback for incoming queries */
472	if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
473		NETEVENT_NOERROR, &repinfo)) {
474		/* send immediate reply */
475		comm_point_send_reply(&repinfo);
476	}
477	/* clear it again, in case copy not done properly */
478	memset(&repinfo, 0, sizeof(repinfo));
479}
480
481/**
482 * Perform callback for fake pending message.
483 */
484static void
485fake_pending_callback(struct replay_runtime* runtime,
486	struct replay_moment* todo, int error)
487{
488	struct fake_pending* p = runtime->pending_list;
489	struct comm_reply repinfo;
490	struct comm_point c;
491	void* cb_arg;
492	comm_point_callback_type* cb;
493
494	memset(&c, 0, sizeof(c));
495	if(!p) fatal_exit("No pending queries.");
496	cb_arg = p->cb_arg;
497	cb = p->callback;
498	c.buffer = sldns_buffer_new(runtime->bufsize);
499	c.type = comm_udp;
500	if(p->transport == transport_tcp) {
501		c.type = comm_tcp;
502		c.tcp_timeout_msec = 30000;
503		c.tcp_keepalive = runtime->tcp_seen_keepalive;
504	}
505	if(todo->evt_type == repevt_back_reply && todo->match) {
506		fill_buffer_with_reply(c.buffer, todo->match, p->pkt,
507			p->pkt_len, p->tcp_pkt_counter);
508	}
509	repinfo.c = &c;
510	repinfo.addrlen = p->addrlen;
511	memcpy(&repinfo.addr, &p->addr, p->addrlen);
512	if(!p->serviced) {
513		if(todo->match && todo->match->reply_list->next && !error &&
514			p->tcp_pkt_counter < count_reply_packets(todo->match)) {
515			/* go to next packet next time */
516			p->tcp_pkt_counter++;
517		} else {
518			pending_list_delete(runtime, p);
519		}
520	}
521	if((*cb)(&c, cb_arg, error, &repinfo)) {
522		fatal_exit("unexpected: pending callback returned 1");
523	}
524	/* delete the pending item. */
525	sldns_buffer_free(c.buffer);
526}
527
528/** pass time */
529static void
530moment_assign(struct replay_runtime* runtime, struct replay_moment* mom)
531{
532	char* value = macro_process(runtime->vars, runtime, mom->string);
533	if(!value)
534		fatal_exit("could not process macro step %d", mom->time_step);
535	log_info("assign %s = %s", mom->variable, value);
536	if(!macro_assign(runtime->vars, mom->variable, value))
537		fatal_exit("out of memory storing macro");
538	free(value);
539	if(verbosity >= VERB_ALGO)
540		macro_print_debug(runtime->vars);
541}
542
543/** pass time */
544static void
545time_passes(struct replay_runtime* runtime, struct replay_moment* mom)
546{
547	struct fake_timer *t;
548	struct timeval tv = mom->elapse;
549	if(mom->string) {
550		char* xp = macro_process(runtime->vars, runtime, mom->string);
551		double sec;
552		if(!xp) fatal_exit("could not macro expand %s", mom->string);
553		verbose(VERB_ALGO, "EVAL %s", mom->string);
554		sec = atof(xp);
555		free(xp);
556#ifndef S_SPLINT_S
557		tv.tv_sec = sec;
558		tv.tv_usec = (int)((sec - (double)tv.tv_sec) *1000000. + 0.5);
559#endif
560	}
561	timeval_add(&runtime->now_tv, &tv);
562	runtime->now_secs = (time_t)runtime->now_tv.tv_sec;
563#ifndef S_SPLINT_S
564	log_info("elapsed %d.%6.6d  now %d.%6.6d",
565		(int)tv.tv_sec, (int)tv.tv_usec,
566		(int)runtime->now_tv.tv_sec, (int)runtime->now_tv.tv_usec);
567#endif
568	/* see if any timers have fired; and run them */
569	while( (t=replay_get_oldest_timer(runtime)) ) {
570		t->enabled = 0;
571		log_info("fake_timer callback");
572		fptr_ok(fptr_whitelist_comm_timer(t->cb));
573		(*t->cb)(t->cb_arg);
574	}
575}
576
577/** check autotrust file contents */
578static void
579autotrust_check(struct replay_runtime* runtime, struct replay_moment* mom)
580{
581	char name[1024], line[1024];
582	FILE *in;
583	int lineno = 0, oke=1;
584	char* expanded;
585	struct config_strlist* p;
586	line[sizeof(line)-1] = 0;
587	log_assert(mom->autotrust_id);
588	fake_temp_file("_auto_", mom->autotrust_id, name, sizeof(name));
589	in = fopen(name, "r");
590	if(!in) fatal_exit("could not open %s: %s", name, strerror(errno));
591	for(p=mom->file_content; p; p=p->next) {
592		lineno++;
593		if(!fgets(line, (int)sizeof(line)-1, in)) {
594			log_err("autotrust check failed, could not read line");
595			log_err("file %s, line %d", name, lineno);
596			log_err("should be: %s", p->str);
597			fatal_exit("autotrust_check failed");
598		}
599		if(line[0]) line[strlen(line)-1] = 0; /* remove newline */
600		expanded = macro_process(runtime->vars, runtime, p->str);
601		if(!expanded)
602			fatal_exit("could not expand macro line %d", lineno);
603		if(verbosity >= 7 && strcmp(p->str, expanded) != 0)
604			log_info("expanded '%s' to '%s'", p->str, expanded);
605		if(strcmp(expanded, line) != 0) {
606			log_err("mismatch in file %s, line %d", name, lineno);
607			log_err("file has : %s", line);
608			log_err("should be: %s", expanded);
609			free(expanded);
610			oke = 0;
611			continue;
612		}
613		free(expanded);
614		fprintf(stderr, "%s:%2d ok : %s\n", name, lineno, line);
615	}
616	if(fgets(line, (int)sizeof(line)-1, in)) {
617		log_err("autotrust check failed, extra lines in %s after %d",
618			name, lineno);
619		do {
620			fprintf(stderr, "file has: %s", line);
621		} while(fgets(line, (int)sizeof(line)-1, in));
622		oke = 0;
623	}
624	fclose(in);
625	if(!oke)
626		fatal_exit("autotrust_check STEP %d failed", mom->time_step);
627	log_info("autotrust %s is OK", mom->autotrust_id);
628}
629
630/** check tempfile file contents */
631static void
632tempfile_check(struct replay_runtime* runtime, struct replay_moment* mom)
633{
634	char name[1024], line[1024];
635	FILE *in;
636	int lineno = 0, oke=1;
637	char* expanded;
638	struct config_strlist* p;
639	line[sizeof(line)-1] = 0;
640	log_assert(mom->autotrust_id);
641	fake_temp_file("_temp_", mom->autotrust_id, name, sizeof(name));
642	in = fopen(name, "r");
643	if(!in) fatal_exit("could not open %s: %s", name, strerror(errno));
644	for(p=mom->file_content; p; p=p->next) {
645		lineno++;
646		if(!fgets(line, (int)sizeof(line)-1, in)) {
647			log_err("tempfile check failed, could not read line");
648			log_err("file %s, line %d", name, lineno);
649			log_err("should be: %s", p->str);
650			fatal_exit("tempfile_check failed");
651		}
652		if(line[0]) line[strlen(line)-1] = 0; /* remove newline */
653		expanded = macro_process(runtime->vars, runtime, p->str);
654		if(!expanded)
655			fatal_exit("could not expand macro line %d", lineno);
656		if(verbosity >= 7 && strcmp(p->str, expanded) != 0)
657			log_info("expanded '%s' to '%s'", p->str, expanded);
658		if(strcmp(expanded, line) != 0) {
659			log_err("mismatch in file %s, line %d", name, lineno);
660			log_err("file has : %s", line);
661			log_err("should be: %s", expanded);
662			free(expanded);
663			oke = 0;
664			continue;
665		}
666		free(expanded);
667		fprintf(stderr, "%s:%2d ok : %s\n", name, lineno, line);
668	}
669	if(fgets(line, (int)sizeof(line)-1, in)) {
670		log_err("tempfile check failed, extra lines in %s after %d",
671			name, lineno);
672		do {
673			fprintf(stderr, "file has: %s", line);
674		} while(fgets(line, (int)sizeof(line)-1, in));
675		oke = 0;
676	}
677	fclose(in);
678	if(!oke)
679		fatal_exit("tempfile_check STEP %d failed", mom->time_step);
680	log_info("tempfile %s is OK", mom->autotrust_id);
681}
682
683/** Store RTT in infra cache */
684static void
685do_infra_rtt(struct replay_runtime* runtime)
686{
687	struct replay_moment* now = runtime->now;
688	int rto;
689	size_t dplen = 0;
690	uint8_t* dp = sldns_str2wire_dname(now->variable, &dplen);
691	if(!dp) fatal_exit("cannot parse %s", now->variable);
692	rto = infra_rtt_update(runtime->infra, &now->addr, now->addrlen,
693		dp, dplen, LDNS_RR_TYPE_A, atoi(now->string),
694		-1, runtime->now_secs);
695	log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
696	log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable,
697		atoi(now->string), rto);
698	if(rto == 0) fatal_exit("infra_rtt_update failed");
699	free(dp);
700}
701
702/** perform exponential backoff on the timeout */
703static void
704expon_timeout_backoff(struct replay_runtime* runtime)
705{
706	struct fake_pending* p = runtime->pending_list;
707	int rtt, vs;
708	uint8_t edns_lame_known;
709	int last_rtt, rto;
710	if(!p) return; /* no pending packet to backoff */
711	if(!infra_host(runtime->infra, &p->addr, p->addrlen, p->zone,
712		p->zonelen, runtime->now_secs, &vs, &edns_lame_known, &rtt))
713		return;
714	last_rtt = rtt;
715	rto = infra_rtt_update(runtime->infra, &p->addr, p->addrlen, p->zone,
716		p->zonelen, p->qtype, -1, last_rtt, runtime->now_secs);
717	log_info("infra_rtt_update returned rto %d", rto);
718}
719
720/**
721 * Advance to the next moment.
722 */
723static void
724advance_moment(struct replay_runtime* runtime)
725{
726	if(!runtime->now)
727		runtime->now = runtime->scenario->mom_first;
728	else 	runtime->now = runtime->now->mom_next;
729}
730
731/**
732 * Perform actions or checks determined by the moment.
733 * Also advances the time by one step.
734 * @param runtime: scenario runtime information.
735 */
736static void
737do_moment_and_advance(struct replay_runtime* runtime)
738{
739	struct replay_moment* mom;
740	if(!runtime->now) {
741		advance_moment(runtime);
742		return;
743	}
744	log_info("testbound: do STEP %d %s", runtime->now->time_step,
745		repevt_string(runtime->now->evt_type));
746	switch(runtime->now->evt_type) {
747	case repevt_nothing:
748		advance_moment(runtime);
749		break;
750	case repevt_front_query:
751		/* advance moment before doing the step, so that the next
752		   moment which may check some result of the mom step
753		   can catch those results. */
754		mom = runtime->now;
755		advance_moment(runtime);
756		fake_front_query(runtime, mom);
757		break;
758	case repevt_front_reply:
759		if(runtime->answer_list)
760			log_err("testbound: There are unmatched answers.");
761		fatal_exit("testbound: query answer not matched");
762		break;
763	case repevt_timeout:
764		mom = runtime->now;
765		advance_moment(runtime);
766		expon_timeout_backoff(runtime);
767		fake_pending_callback(runtime, mom, NETEVENT_TIMEOUT);
768		break;
769	case repevt_back_reply:
770		mom = runtime->now;
771		advance_moment(runtime);
772		fake_pending_callback(runtime, mom, NETEVENT_NOERROR);
773		break;
774	case repevt_back_query:
775		/* Back queries are matched when they are sent out. */
776		log_err("No query matching the current moment was sent.");
777		fatal_exit("testbound: back query not matched");
778		break;
779	case repevt_error:
780		mom = runtime->now;
781		advance_moment(runtime);
782		fake_pending_callback(runtime, mom, NETEVENT_CLOSED);
783		break;
784	case repevt_time_passes:
785		time_passes(runtime, runtime->now);
786		advance_moment(runtime);
787		break;
788	case repevt_autotrust_check:
789		autotrust_check(runtime, runtime->now);
790		advance_moment(runtime);
791		break;
792	case repevt_tempfile_check:
793		tempfile_check(runtime, runtime->now);
794		advance_moment(runtime);
795		break;
796	case repevt_assign:
797		moment_assign(runtime, runtime->now);
798		advance_moment(runtime);
799		break;
800	case repevt_traffic:
801		advance_moment(runtime);
802		break;
803	case repevt_infra_rtt:
804		do_infra_rtt(runtime);
805		advance_moment(runtime);
806		break;
807	default:
808		fatal_exit("testbound: unknown event type %d",
809			runtime->now->evt_type);
810	}
811}
812
813/** run the scenario in event callbacks */
814static void
815run_scenario(struct replay_runtime* runtime)
816{
817	struct entry* entry = NULL;
818	struct fake_pending* pending = NULL;
819	int max_rounds = 5000;
820	int rounds = 0;
821	runtime->now = runtime->scenario->mom_first;
822	log_info("testbound: entering fake runloop");
823	do {
824		/* if moment matches pending query do it. */
825		/* else if moment matches given answer, do it */
826		/* else if precoded_range matches pending, do it */
827		/* else do the current moment */
828		if(pending_matches_current(runtime, &entry, &pending)) {
829			log_info("testbound: do STEP %d CHECK_OUT_QUERY",
830				runtime->now->time_step);
831			advance_moment(runtime);
832			if(entry->copy_id)
833				answer_callback_from_entry(runtime, entry,
834				pending);
835		} else if(runtime->answer_list && runtime->now &&
836			runtime->now->evt_type == repevt_front_reply) {
837			answer_check_it(runtime);
838			advance_moment(runtime);
839		} else if(pending_matches_range(runtime, &entry, &pending)) {
840			answer_callback_from_entry(runtime, entry, pending);
841		} else {
842			do_moment_and_advance(runtime);
843		}
844		log_info("testbound: end of event stage");
845		rounds++;
846		if(rounds > max_rounds)
847			fatal_exit("testbound: too many rounds, it loops.");
848	} while(runtime->now);
849
850	if(runtime->pending_list) {
851		struct fake_pending* p;
852		log_err("testbound: there are still messages pending.");
853		for(p = runtime->pending_list; p; p=p->next) {
854			log_pkt("pending msg", p->pkt, p->pkt_len);
855			log_addr(0, "pending to", &p->addr, p->addrlen);
856		}
857		fatal_exit("testbound: there are still messages pending.");
858	}
859	if(runtime->answer_list) {
860		fatal_exit("testbound: there are unmatched answers.");
861	}
862	log_info("testbound: exiting fake runloop.");
863	runtime->exit_cleanly = 1;
864}
865
866/*********** Dummy routines ***********/
867
868struct listen_dnsport*
869listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
870	size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
871	int ATTR_UNUSED(tcp_idle_timeout),
872	int ATTR_UNUSED(harden_large_queries),
873	uint32_t ATTR_UNUSED(http_max_streams),
874	char* ATTR_UNUSED(http_endpoint),
875	int ATTR_UNUSED(http_notls),
876	struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
877	void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
878	comm_point_callback_type* cb, void *cb_arg)
879{
880	struct replay_runtime* runtime = (struct replay_runtime*)base;
881	struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport));
882	if(!l)
883		return NULL;
884	l->base = base;
885	l->udp_buff = sldns_buffer_new(bufsize);
886	if(!l->udp_buff) {
887		free(l);
888		return NULL;
889	}
890	runtime->callback_query = cb;
891	runtime->cb_arg = cb_arg;
892	runtime->bufsize = bufsize;
893	return l;
894}
895
896void
897listen_delete(struct listen_dnsport* listen)
898{
899	if(!listen)
900		return;
901	sldns_buffer_free(listen->udp_buff);
902	free(listen);
903}
904
905struct comm_base*
906comm_base_create(int ATTR_UNUSED(sigs))
907{
908	/* we return the runtime structure instead. */
909	struct replay_runtime* runtime = (struct replay_runtime*)
910		calloc(1, sizeof(struct replay_runtime));
911	runtime->scenario = saved_scenario;
912	runtime->vars = macro_store_create();
913	if(!runtime->vars) fatal_exit("out of memory");
914	return (struct comm_base*)runtime;
915}
916
917void
918comm_base_delete(struct comm_base* b)
919{
920	struct replay_runtime* runtime = (struct replay_runtime*)b;
921	struct fake_pending* p, *np;
922	struct replay_answer* a, *na;
923	struct fake_timer* t, *nt;
924	if(!runtime)
925		return;
926	runtime->scenario= NULL;
927	p = runtime->pending_list;
928	while(p) {
929		np = p->next;
930		delete_fake_pending(p);
931		p = np;
932	}
933	a = runtime->answer_list;
934	while(a) {
935		na = a->next;
936		delete_replay_answer(a);
937		a = na;
938	}
939	t = runtime->timer_list;
940	while(t) {
941		nt = t->next;
942		free(t);
943		t = nt;
944	}
945	macro_store_delete(runtime->vars);
946	free(runtime);
947}
948
949void
950comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv)
951{
952	struct replay_runtime* runtime = (struct replay_runtime*)b;
953	*tt = &runtime->now_secs;
954	*tv = &runtime->now_tv;
955}
956
957void
958comm_base_dispatch(struct comm_base* b)
959{
960	struct replay_runtime* runtime = (struct replay_runtime*)b;
961	run_scenario(runtime);
962	if(runtime->sig_cb)
963		(*runtime->sig_cb)(SIGTERM, runtime->sig_cb_arg);
964	else	exit(0); /* OK exit when LIBEVENT_SIGNAL_PROBLEM exists */
965}
966
967void
968comm_base_exit(struct comm_base* b)
969{
970	struct replay_runtime* runtime = (struct replay_runtime*)b;
971	if(!runtime->exit_cleanly) {
972		/* some sort of failure */
973		fatal_exit("testbound: comm_base_exit was called.");
974	}
975}
976
977struct comm_signal*
978comm_signal_create(struct comm_base* base,
979        void (*callback)(int, void*), void* cb_arg)
980{
981	struct replay_runtime* runtime = (struct replay_runtime*)base;
982	runtime->sig_cb = callback;
983	runtime->sig_cb_arg = cb_arg;
984	return calloc(1, sizeof(struct comm_signal));
985}
986
987int
988comm_signal_bind(struct comm_signal* ATTR_UNUSED(comsig), int
989	ATTR_UNUSED(sig))
990{
991	return 1;
992}
993
994void
995comm_signal_delete(struct comm_signal* comsig)
996{
997	free(comsig);
998}
999
1000void
1001comm_point_send_reply(struct comm_reply* repinfo)
1002{
1003	struct replay_answer* ans = (struct replay_answer*)calloc(1,
1004		sizeof(struct replay_answer));
1005	struct replay_runtime* runtime = (struct replay_runtime*)repinfo->c->ev;
1006	log_info("testbound: comm_point_send_reply fake");
1007	/* dump it into the todo list */
1008	log_assert(ans);
1009	memcpy(&ans->repinfo, repinfo, sizeof(struct comm_reply));
1010	ans->next = NULL;
1011	if(runtime->answer_last)
1012		runtime->answer_last->next = ans;
1013	else 	runtime->answer_list = ans;
1014	runtime->answer_last = ans;
1015
1016	/* try to parse packet */
1017	ans->pkt = memdup(sldns_buffer_begin(ans->repinfo.c->buffer),
1018		sldns_buffer_limit(ans->repinfo.c->buffer));
1019	ans->pkt_len = sldns_buffer_limit(ans->repinfo.c->buffer);
1020	if(!ans->pkt) fatal_exit("out of memory");
1021	log_pkt("reply pkt: ", ans->pkt, ans->pkt_len);
1022}
1023
1024void
1025comm_point_drop_reply(struct comm_reply* repinfo)
1026{
1027	log_info("comm_point_drop_reply fake");
1028	if(repinfo->c) {
1029		sldns_buffer_free(repinfo->c->buffer);
1030		free(repinfo->c);
1031	}
1032}
1033
1034struct outside_network*
1035outside_network_create(struct comm_base* base, size_t bufsize,
1036	size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs),
1037	int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
1038	int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
1039	int ATTR_UNUSED(dscp),
1040	struct infra_cache* infra,
1041	struct ub_randstate* ATTR_UNUSED(rnd),
1042	int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
1043	int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
1044	int ATTR_UNUSED(outgoing_tcp_mss),
1045	void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
1046	int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
1047	int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
1048	struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect))
1049{
1050	struct replay_runtime* runtime = (struct replay_runtime*)base;
1051	struct outside_network* outnet =  calloc(1,
1052		sizeof(struct outside_network));
1053	(void)unwanted_action;
1054	if(!outnet)
1055		return NULL;
1056	runtime->infra = infra;
1057	outnet->base = base;
1058	outnet->udp_buff = sldns_buffer_new(bufsize);
1059	if(!outnet->udp_buff) {
1060		free(outnet);
1061		return NULL;
1062	}
1063	return outnet;
1064}
1065
1066void
1067outside_network_delete(struct outside_network* outnet)
1068{
1069	if(!outnet)
1070		return;
1071	sldns_buffer_free(outnet->udp_buff);
1072	free(outnet);
1073}
1074
1075void
1076outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
1077{
1078}
1079
1080struct pending*
1081pending_udp_query(struct serviced_query* sq, sldns_buffer* packet,
1082	int timeout, comm_point_callback_type* callback, void* callback_arg)
1083{
1084	struct replay_runtime* runtime = (struct replay_runtime*)
1085		sq->outnet->base;
1086	struct fake_pending* pend = (struct fake_pending*)calloc(1,
1087		sizeof(struct fake_pending));
1088	log_assert(pend);
1089	pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet));
1090	log_assert(pend->buffer);
1091	sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet),
1092		sldns_buffer_limit(packet));
1093	sldns_buffer_flip(pend->buffer);
1094	memcpy(&pend->addr, &sq->addr, sq->addrlen);
1095	pend->addrlen = sq->addrlen;
1096	pend->callback = callback;
1097	pend->cb_arg = callback_arg;
1098	pend->timeout = timeout/1000;
1099	pend->transport = transport_udp;
1100	pend->pkt = NULL;
1101	pend->zone = NULL;
1102	pend->serviced = 0;
1103	pend->runtime = runtime;
1104	pend->pkt_len = sldns_buffer_limit(packet);
1105	pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len);
1106	if(!pend->pkt) fatal_exit("out of memory");
1107	log_pkt("pending udp pkt: ", pend->pkt, pend->pkt_len);
1108
1109	/* see if it matches the current moment */
1110	if(runtime->now && runtime->now->evt_type == repevt_back_query &&
1111		(runtime->now->addrlen == 0 || sockaddr_cmp(
1112			&runtime->now->addr, runtime->now->addrlen,
1113			&pend->addr, pend->addrlen) == 0) &&
1114		find_match(runtime->now->match, pend->pkt, pend->pkt_len,
1115			pend->transport)) {
1116		log_info("testbound: matched pending to event. "
1117			"advance time between events.");
1118		log_info("testbound: do STEP %d %s", runtime->now->time_step,
1119			repevt_string(runtime->now->evt_type));
1120		advance_moment(runtime);
1121		/* still create the pending, because we need it to callback */
1122	}
1123	log_info("testbound: created fake pending");
1124	/* add to list */
1125	pend->next = runtime->pending_list;
1126	runtime->pending_list = pend;
1127	return (struct pending*)pend;
1128}
1129
1130struct waiting_tcp*
1131pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
1132	int timeout, comm_point_callback_type* callback, void* callback_arg)
1133{
1134	struct replay_runtime* runtime = (struct replay_runtime*)
1135		sq->outnet->base;
1136	struct fake_pending* pend = (struct fake_pending*)calloc(1,
1137		sizeof(struct fake_pending));
1138	log_assert(pend);
1139	pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet));
1140	log_assert(pend->buffer);
1141	sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet),
1142		sldns_buffer_limit(packet));
1143	sldns_buffer_flip(pend->buffer);
1144	memcpy(&pend->addr, &sq->addr, sq->addrlen);
1145	pend->addrlen = sq->addrlen;
1146	pend->callback = callback;
1147	pend->cb_arg = callback_arg;
1148	pend->timeout = timeout/1000;
1149	pend->transport = transport_tcp;
1150	pend->pkt = NULL;
1151	pend->zone = NULL;
1152	pend->runtime = runtime;
1153	pend->serviced = 0;
1154	pend->pkt_len = sldns_buffer_limit(packet);
1155	pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len);
1156	if(!pend->pkt) fatal_exit("out of memory");
1157	log_pkt("pending tcp pkt: ", pend->pkt, pend->pkt_len);
1158
1159	/* see if it matches the current moment */
1160	if(runtime->now && runtime->now->evt_type == repevt_back_query &&
1161		(runtime->now->addrlen == 0 || sockaddr_cmp(
1162			&runtime->now->addr, runtime->now->addrlen,
1163			&pend->addr, pend->addrlen) == 0) &&
1164		find_match(runtime->now->match, pend->pkt, pend->pkt_len,
1165			pend->transport)) {
1166		log_info("testbound: matched pending to event. "
1167			"advance time between events.");
1168		log_info("testbound: do STEP %d %s", runtime->now->time_step,
1169			repevt_string(runtime->now->evt_type));
1170		advance_moment(runtime);
1171		/* still create the pending, because we need it to callback */
1172	}
1173	log_info("testbound: created fake pending");
1174	/* add to list */
1175	pend->next = runtime->pending_list;
1176	runtime->pending_list = pend;
1177	return (struct waiting_tcp*)pend;
1178}
1179
1180struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
1181	struct query_info* qinfo, uint16_t flags, int dnssec,
1182	int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
1183	int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
1184	char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
1185	socklen_t addrlen, uint8_t* zone, size_t zonelen,
1186	struct module_qstate* qstate, comm_point_callback_type* callback,
1187	void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
1188	struct module_env* env)
1189{
1190	struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
1191	struct fake_pending* pend = (struct fake_pending*)calloc(1,
1192		sizeof(struct fake_pending));
1193	char z[256];
1194	log_assert(pend);
1195	log_nametypeclass(VERB_OPS, "pending serviced query",
1196		qinfo->qname, qinfo->qtype, qinfo->qclass);
1197	dname_str(zone, z);
1198	verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s",
1199		z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"",
1200		(flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":"");
1201
1202	/* create packet with EDNS */
1203	pend->buffer = sldns_buffer_new(512);
1204	log_assert(pend->buffer);
1205	sldns_buffer_write_u16(pend->buffer, 0); /* id */
1206	sldns_buffer_write_u16(pend->buffer, flags);
1207	sldns_buffer_write_u16(pend->buffer, 1); /* qdcount */
1208	sldns_buffer_write_u16(pend->buffer, 0); /* ancount */
1209	sldns_buffer_write_u16(pend->buffer, 0); /* nscount */
1210	sldns_buffer_write_u16(pend->buffer, 0); /* arcount */
1211	sldns_buffer_write(pend->buffer, qinfo->qname, qinfo->qname_len);
1212	sldns_buffer_write_u16(pend->buffer, qinfo->qtype);
1213	sldns_buffer_write_u16(pend->buffer, qinfo->qclass);
1214	sldns_buffer_flip(pend->buffer);
1215	if(1) {
1216		struct edns_data edns;
1217		struct edns_string_addr* client_string_addr;
1218		if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen,
1219			zone, zonelen, qstate, qstate->region)) {
1220			free(pend);
1221			return NULL;
1222		}
1223		/* add edns */
1224		edns.edns_present = 1;
1225		edns.ext_rcode = 0;
1226		edns.edns_version = EDNS_ADVERTISED_VERSION;
1227		edns.udp_size = EDNS_ADVERTISED_SIZE;
1228		edns.bits = 0;
1229		if(dnssec)
1230			edns.bits = EDNS_DO;
1231		if((client_string_addr = edns_string_addr_lookup(
1232			&env->edns_strings->client_strings,
1233			addr, addrlen))) {
1234			edns_opt_list_append(&qstate->edns_opts_back_out,
1235				env->edns_strings->client_string_opcode,
1236				client_string_addr->string_len,
1237				client_string_addr->string, qstate->region);
1238		}
1239		edns.opt_list = qstate->edns_opts_back_out;
1240		attach_edns_record(pend->buffer, &edns);
1241	}
1242	memcpy(&pend->addr, addr, addrlen);
1243	pend->addrlen = addrlen;
1244	pend->zone = memdup(zone, zonelen);
1245	pend->zonelen = zonelen;
1246	pend->qtype = (int)qinfo->qtype;
1247	log_assert(pend->zone);
1248	pend->callback = callback;
1249	pend->cb_arg = callback_arg;
1250	pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
1251	pend->transport = transport_udp; /* pretend UDP */
1252	pend->pkt = NULL;
1253	pend->runtime = runtime;
1254	pend->serviced = 1;
1255	pend->pkt_len = sldns_buffer_limit(pend->buffer);
1256	pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len);
1257	if(!pend->pkt) fatal_exit("out of memory");
1258	/*log_pkt("pending serviced query: ", pend->pkt, pend->pkt_len);*/
1259
1260	/* see if it matches the current moment */
1261	if(runtime->now && runtime->now->evt_type == repevt_back_query &&
1262		(runtime->now->addrlen == 0 || sockaddr_cmp(
1263			&runtime->now->addr, runtime->now->addrlen,
1264			&pend->addr, pend->addrlen) == 0) &&
1265		find_match(runtime->now->match, pend->pkt, pend->pkt_len,
1266			pend->transport)) {
1267		log_info("testbound: matched pending to event. "
1268			"advance time between events.");
1269		log_info("testbound: do STEP %d %s", runtime->now->time_step,
1270			repevt_string(runtime->now->evt_type));
1271		advance_moment(runtime);
1272		/* still create the pending, because we need it to callback */
1273	}
1274	log_info("testbound: created fake pending");
1275	/* add to list */
1276	pend->next = runtime->pending_list;
1277	runtime->pending_list = pend;
1278	return (struct serviced_query*)pend;
1279}
1280
1281void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
1282{
1283	struct fake_pending* pend = (struct fake_pending*)sq;
1284	struct replay_runtime* runtime = pend->runtime;
1285	/* delete from the list */
1286	struct fake_pending* p = runtime->pending_list, *prev=NULL;
1287	while(p) {
1288		if(p == pend) {
1289			log_assert(p->cb_arg == cb_arg);
1290			(void)cb_arg;
1291			log_info("serviced pending delete");
1292			if(prev)
1293				prev->next = p->next;
1294			else 	runtime->pending_list = p->next;
1295			sldns_buffer_free(p->buffer);
1296			free(p->pkt);
1297			free(p->zone);
1298			free(p);
1299			return;
1300		}
1301		prev = p;
1302		p = p->next;
1303	}
1304	log_info("double delete of pending serviced query");
1305}
1306
1307int resolve_interface_names(struct config_file* ATTR_UNUSED(cfg),
1308	char*** ATTR_UNUSED(resif), int* ATTR_UNUSED(num_resif))
1309{
1310	return 1;
1311}
1312
1313struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg),
1314	char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs),
1315	int* ATTR_UNUSED(reuseport))
1316{
1317	return calloc(1, 1);
1318}
1319
1320void listening_ports_free(struct listen_port* list)
1321{
1322	free(list);
1323}
1324
1325struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
1326        int ATTR_UNUSED(fd), size_t ATTR_UNUSED(bufsize),
1327        comm_point_callback_type* ATTR_UNUSED(callback),
1328	void* ATTR_UNUSED(callback_arg))
1329{
1330	struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
1331		sizeof(*fc));
1332	if(!fc) return NULL;
1333	fc->typecode = FAKE_COMMPOINT_TYPECODE;
1334	return (struct comm_point*)fc;
1335}
1336
1337struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base),
1338        int ATTR_UNUSED(fd), int ATTR_UNUSED(writing),
1339        comm_point_callback_type* ATTR_UNUSED(callback),
1340	void* ATTR_UNUSED(callback_arg))
1341{
1342	/* no pipe comm possible */
1343	struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
1344		sizeof(*fc));
1345	if(!fc) return NULL;
1346	fc->typecode = FAKE_COMMPOINT_TYPECODE;
1347	return (struct comm_point*)fc;
1348}
1349
1350void comm_point_start_listening(struct comm_point* ATTR_UNUSED(c),
1351	int ATTR_UNUSED(newfd), int ATTR_UNUSED(sec))
1352{
1353	/* no bg write pipe comm possible */
1354}
1355
1356void comm_point_stop_listening(struct comm_point* ATTR_UNUSED(c))
1357{
1358	/* no bg write pipe comm possible */
1359}
1360
1361/* only cmd com _local gets deleted */
1362void comm_point_delete(struct comm_point* c)
1363{
1364	struct fake_commpoint* fc = (struct fake_commpoint*)c;
1365	if(c == NULL) return;
1366	log_assert(fc->typecode == FAKE_COMMPOINT_TYPECODE);
1367	if(fc->type_tcp_out) {
1368		/* remove tcp pending, so no more callbacks to it */
1369		pending_list_delete(fc->runtime, fc->pending);
1370	}
1371	free(c);
1372}
1373
1374size_t listen_get_mem(struct listen_dnsport* ATTR_UNUSED(listen))
1375{
1376	return 0;
1377}
1378
1379size_t outnet_get_mem(struct outside_network* ATTR_UNUSED(outnet))
1380{
1381	return 0;
1382}
1383
1384size_t comm_point_get_mem(struct comm_point* ATTR_UNUSED(c))
1385{
1386	return 0;
1387}
1388
1389size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c))
1390{
1391	return 0;
1392}
1393
1394/* fake for fptr wlist */
1395int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c),
1396	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1397        struct comm_reply *ATTR_UNUSED(reply_info))
1398{
1399	log_assert(0);
1400	return 0;
1401}
1402
1403int outnet_tcp_cb(struct comm_point* ATTR_UNUSED(c),
1404	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1405        struct comm_reply *ATTR_UNUSED(reply_info))
1406{
1407	log_assert(0);
1408	return 0;
1409}
1410
1411void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
1412{
1413	log_assert(0);
1414}
1415
1416void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg))
1417{
1418	log_assert(0);
1419}
1420
1421void outnet_tcptimer(void* ATTR_UNUSED(arg))
1422{
1423	log_assert(0);
1424}
1425
1426void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
1427	void* ATTR_UNUSED(arg))
1428{
1429	log_assert(0);
1430}
1431
1432void comm_point_udp_ancil_callback(int ATTR_UNUSED(fd),
1433	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1434{
1435	log_assert(0);
1436}
1437
1438void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd),
1439	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1440{
1441	log_assert(0);
1442}
1443
1444void comm_point_tcp_handle_callback(int ATTR_UNUSED(fd),
1445	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1446{
1447	log_assert(0);
1448}
1449
1450void comm_timer_callback(int ATTR_UNUSED(fd),
1451	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1452{
1453	log_assert(0);
1454}
1455
1456void comm_signal_callback(int ATTR_UNUSED(fd),
1457	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1458{
1459	log_assert(0);
1460}
1461
1462void comm_point_http_handle_callback(int ATTR_UNUSED(fd),
1463	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1464{
1465	log_assert(0);
1466}
1467
1468void comm_point_local_handle_callback(int ATTR_UNUSED(fd),
1469	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1470{
1471	log_assert(0);
1472}
1473
1474void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
1475	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1476{
1477	log_assert(0);
1478}
1479
1480void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
1481	short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1482{
1483	log_assert(0);
1484}
1485
1486int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c),
1487	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1488        struct comm_reply* ATTR_UNUSED(reply_info))
1489{
1490	log_assert(0);
1491	return 0;
1492}
1493
1494int serviced_tcp_callback(struct comm_point* ATTR_UNUSED(c),
1495	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1496        struct comm_reply* ATTR_UNUSED(reply_info))
1497{
1498	log_assert(0);
1499	return 0;
1500}
1501
1502int pending_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1503{
1504	log_assert(0);
1505	return 0;
1506}
1507
1508int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1509{
1510	log_assert(0);
1511	return 0;
1512}
1513
1514int reuse_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1515{
1516	log_assert(0);
1517	return 0;
1518}
1519
1520int reuse_id_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1521{
1522	log_assert(0);
1523	return 0;
1524}
1525
1526/* timers in testbound for autotrust. statistics tested in tdir. */
1527struct comm_timer* comm_timer_create(struct comm_base* base,
1528	void (*cb)(void*), void* cb_arg)
1529{
1530	struct replay_runtime* runtime = (struct replay_runtime*)base;
1531	struct fake_timer* t = (struct fake_timer*)calloc(1, sizeof(*t));
1532	t->cb = cb;
1533	t->cb_arg = cb_arg;
1534	fptr_ok(fptr_whitelist_comm_timer(t->cb)); /* check in advance */
1535	t->runtime = runtime;
1536	t->next = runtime->timer_list;
1537	runtime->timer_list = t;
1538	return (struct comm_timer*)t;
1539}
1540
1541void comm_timer_disable(struct comm_timer* timer)
1542{
1543	struct fake_timer* t = (struct fake_timer*)timer;
1544	log_info("fake timer disabled");
1545	t->enabled = 0;
1546}
1547
1548void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
1549{
1550	struct fake_timer* t = (struct fake_timer*)timer;
1551	t->enabled = 1;
1552	t->tv = *tv;
1553	log_info("fake timer set %d.%6.6d",
1554		(int)t->tv.tv_sec, (int)t->tv.tv_usec);
1555	timeval_add(&t->tv, &t->runtime->now_tv);
1556}
1557
1558void comm_timer_delete(struct comm_timer* timer)
1559{
1560	struct fake_timer* t = (struct fake_timer*)timer;
1561	struct fake_timer** pp, *p;
1562	if(!t) return;
1563
1564	/* remove from linked list */
1565	pp = &t->runtime->timer_list;
1566	p = t->runtime->timer_list;
1567	while(p) {
1568		if(p == t) {
1569			/* snip from list */
1570			*pp = p->next;
1571			break;
1572		}
1573		pp = &p->next;
1574		p = p->next;
1575	}
1576
1577	free(timer);
1578}
1579
1580void comm_base_set_slow_accept_handlers(struct comm_base* ATTR_UNUSED(b),
1581	void (*stop_acc)(void*), void (*start_acc)(void*),
1582	void* ATTR_UNUSED(arg))
1583{
1584	/* ignore this */
1585	(void)stop_acc;
1586	(void)start_acc;
1587}
1588
1589struct ub_event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
1590{
1591	/* no pipe comm possible in testbound */
1592	return NULL;
1593}
1594
1595void daemon_remote_exec(struct worker* ATTR_UNUSED(worker))
1596{
1597}
1598
1599void listen_start_accept(struct listen_dnsport* ATTR_UNUSED(listen))
1600{
1601}
1602
1603void listen_stop_accept(struct listen_dnsport* ATTR_UNUSED(listen))
1604{
1605}
1606
1607void daemon_remote_start_accept(struct daemon_remote* ATTR_UNUSED(rc))
1608{
1609}
1610
1611void daemon_remote_stop_accept(struct daemon_remote* ATTR_UNUSED(rc))
1612{
1613}
1614
1615int create_udp_sock(int ATTR_UNUSED(family), int ATTR_UNUSED(socktype),
1616	struct sockaddr* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
1617	int ATTR_UNUSED(v6only), int* ATTR_UNUSED(inuse),
1618	int* ATTR_UNUSED(noproto), int ATTR_UNUSED(rcv), int ATTR_UNUSED(snd),
1619	int ATTR_UNUSED(listen), int* ATTR_UNUSED(reuseport),
1620	int ATTR_UNUSED(transparent), int ATTR_UNUSED(freebind),
1621	int ATTR_UNUSED(use_systemd), int ATTR_UNUSED(dscp))
1622{
1623	/* if you actually print to this, it'll be stdout during test */
1624	return 1;
1625}
1626
1627struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base),
1628	int ATTR_UNUSED(fd), sldns_buffer* ATTR_UNUSED(buffer),
1629	comm_point_callback_type* ATTR_UNUSED(callback),
1630	void* ATTR_UNUSED(callback_arg))
1631{
1632	log_assert(0);
1633	return NULL;
1634}
1635
1636struct comm_point* comm_point_create_tcp_out(struct comm_base*
1637	ATTR_UNUSED(base), size_t ATTR_UNUSED(bufsize),
1638	comm_point_callback_type* ATTR_UNUSED(callback),
1639	void* ATTR_UNUSED(callback_arg))
1640{
1641	log_assert(0);
1642	return NULL;
1643}
1644
1645struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
1646	comm_point_callback_type* cb, void* cb_arg,
1647	struct sockaddr_storage* ATTR_UNUSED(to_addr),
1648	socklen_t ATTR_UNUSED(to_addrlen))
1649{
1650	struct replay_runtime* runtime = (struct replay_runtime*)
1651		outnet->base;
1652	struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
1653		sizeof(*fc));
1654	if(!fc) return NULL;
1655	fc->typecode = FAKE_COMMPOINT_TYPECODE;
1656	fc->type_udp_out = 1;
1657	fc->cb = cb;
1658	fc->cb_arg = cb_arg;
1659	fc->runtime = runtime;
1660	/* used by authzone transfers */
1661	return (struct comm_point*)fc;
1662}
1663
1664struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
1665	comm_point_callback_type* cb, void* cb_arg,
1666	struct sockaddr_storage* to_addr, socklen_t to_addrlen,
1667	struct sldns_buffer* query, int timeout, int ATTR_UNUSED(ssl),
1668	char* ATTR_UNUSED(host))
1669{
1670	struct replay_runtime* runtime = (struct replay_runtime*)
1671		outnet->base;
1672	struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
1673		sizeof(*fc));
1674	struct fake_pending* pend = (struct fake_pending*)calloc(1,
1675		sizeof(struct fake_pending));
1676	if(!fc || !pend) {
1677		free(fc);
1678		free(pend);
1679		return NULL;
1680	}
1681	fc->typecode = FAKE_COMMPOINT_TYPECODE;
1682	fc->type_tcp_out = 1;
1683	fc->cb = cb;
1684	fc->cb_arg = cb_arg;
1685	fc->runtime = runtime;
1686	fc->pending = pend;
1687
1688	/* used by authzone transfers */
1689	/* create pending item */
1690	pend->buffer = sldns_buffer_new(sldns_buffer_limit(query)+10);
1691	if(!pend->buffer) {
1692		free(fc);
1693		free(pend);
1694		return NULL;
1695	}
1696	sldns_buffer_copy(pend->buffer, query);
1697	memcpy(&pend->addr, to_addr, to_addrlen);
1698	pend->addrlen = to_addrlen;
1699	pend->zone = NULL;
1700	pend->zonelen = 0;
1701	if(LDNS_QDCOUNT(sldns_buffer_begin(query)) > 0) {
1702		char buf[512];
1703		char addrbuf[128];
1704		(void)sldns_wire2str_rrquestion_buf(sldns_buffer_at(query, LDNS_HEADER_SIZE), sldns_buffer_limit(query)-LDNS_HEADER_SIZE, buf, sizeof(buf));
1705		addr_to_str((struct sockaddr_storage*)to_addr, to_addrlen,
1706			addrbuf, sizeof(addrbuf));
1707		if(verbosity >= VERB_ALGO) {
1708			if(buf[0] != 0) buf[strlen(buf)-1] = 0; /* del newline*/
1709			log_info("tcp to %s: %s", addrbuf, buf);
1710		}
1711		log_assert(sldns_buffer_limit(query)-LDNS_HEADER_SIZE >= 2);
1712		pend->qtype = (int)sldns_buffer_read_u16_at(query,
1713			LDNS_HEADER_SIZE+
1714			dname_valid(sldns_buffer_at(query, LDNS_HEADER_SIZE),
1715				sldns_buffer_limit(query)-LDNS_HEADER_SIZE));
1716	}
1717	pend->callback = cb;
1718	pend->cb_arg = cb_arg;
1719	pend->timeout = timeout;
1720	pend->transport = transport_tcp;
1721	pend->pkt = NULL;
1722	pend->runtime = runtime;
1723	pend->serviced = 0;
1724	pend->pkt_len = sldns_buffer_limit(pend->buffer);
1725	pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len);
1726	if(!pend->pkt) fatal_exit("out of memory");
1727
1728	log_info("testbound: created fake pending for tcp_out");
1729
1730	/* add to list */
1731	pend->next = runtime->pending_list;
1732	runtime->pending_list = pend;
1733
1734	return (struct comm_point*)fc;
1735}
1736
1737struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
1738	comm_point_callback_type* cb, void* cb_arg,
1739	struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout,
1740	int ssl, char* host, char* path)
1741{
1742	struct replay_runtime* runtime = (struct replay_runtime*)
1743		outnet->base;
1744	struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1,
1745		sizeof(*fc));
1746	if(!fc) {
1747		return NULL;
1748	}
1749	fc->typecode = FAKE_COMMPOINT_TYPECODE;
1750	fc->type_http_out = 1;
1751	fc->cb = cb;
1752	fc->cb_arg = cb_arg;
1753	fc->runtime = runtime;
1754
1755	(void)to_addr;
1756	(void)to_addrlen;
1757	(void)timeout;
1758
1759	(void)ssl;
1760	(void)host;
1761	(void)path;
1762
1763	/* handle http comm point and return contents from test script */
1764	return (struct comm_point*)fc;
1765}
1766
1767int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
1768	struct sockaddr* addr, socklen_t addrlen, int ATTR_UNUSED(is_connected))
1769{
1770	struct fake_commpoint* fc = (struct fake_commpoint*)c;
1771	struct replay_runtime* runtime = fc->runtime;
1772	struct fake_pending* pend = (struct fake_pending*)calloc(1,
1773		sizeof(struct fake_pending));
1774	if(!pend) {
1775		log_err("malloc failure");
1776		return 0;
1777	}
1778	fc->pending = pend;
1779	/* used by authzone transfers */
1780	/* create pending item */
1781	pend->buffer = sldns_buffer_new(sldns_buffer_limit(packet) + 10);
1782	if(!pend->buffer) {
1783		free(pend);
1784		return 0;
1785	}
1786	sldns_buffer_copy(pend->buffer, packet);
1787	memcpy(&pend->addr, addr, addrlen);
1788	pend->addrlen = addrlen;
1789	pend->zone = NULL;
1790	pend->zonelen = 0;
1791	if(LDNS_QDCOUNT(sldns_buffer_begin(packet)) > 0) {
1792		char buf[512];
1793		char addrbuf[128];
1794		(void)sldns_wire2str_rrquestion_buf(sldns_buffer_at(packet, LDNS_HEADER_SIZE), sldns_buffer_limit(packet)-LDNS_HEADER_SIZE, buf, sizeof(buf));
1795		addr_to_str((struct sockaddr_storage*)addr, addrlen,
1796			addrbuf, sizeof(addrbuf));
1797		if(verbosity >= VERB_ALGO) {
1798			if(buf[0] != 0) buf[strlen(buf)-1] = 0; /* del newline*/
1799			log_info("udp to %s: %s", addrbuf, buf);
1800		}
1801		log_assert(sldns_buffer_limit(packet)-LDNS_HEADER_SIZE >= 2);
1802		pend->qtype = (int)sldns_buffer_read_u16_at(packet,
1803			LDNS_HEADER_SIZE+
1804			dname_valid(sldns_buffer_at(packet, LDNS_HEADER_SIZE),
1805				sldns_buffer_limit(packet)-LDNS_HEADER_SIZE));
1806	}
1807	pend->callback = fc->cb;
1808	pend->cb_arg = fc->cb_arg;
1809	pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
1810	pend->transport = transport_udp;
1811	pend->pkt = NULL;
1812	pend->runtime = runtime;
1813	pend->serviced = 0;
1814	pend->pkt_len = sldns_buffer_limit(pend->buffer);
1815	pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len);
1816	if(!pend->pkt) fatal_exit("out of memory");
1817
1818	log_info("testbound: created fake pending for send_udp_msg");
1819
1820	/* add to list */
1821	pend->next = runtime->pending_list;
1822	runtime->pending_list = pend;
1823
1824	return 1;
1825}
1826
1827int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
1828	socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), int ATTR_UNUSED(dscp))
1829{
1830	log_assert(0);
1831	return -1;
1832}
1833
1834int outnet_tcp_connect(int ATTR_UNUSED(s), struct sockaddr_storage* ATTR_UNUSED(addr),
1835	socklen_t ATTR_UNUSED(addrlen))
1836{
1837	log_assert(0);
1838	return 0;
1839}
1840
1841int tcp_req_info_add_meshstate(struct tcp_req_info* ATTR_UNUSED(req),
1842        struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
1843{
1844	log_assert(0);
1845	return 0;
1846}
1847
1848void
1849tcp_req_info_remove_mesh_state(struct tcp_req_info* ATTR_UNUSED(req),
1850	struct mesh_state* ATTR_UNUSED(m))
1851{
1852	log_assert(0);
1853}
1854
1855size_t
1856tcp_req_info_get_stream_buffer_size(void)
1857{
1858	return 0;
1859}
1860
1861size_t
1862http2_get_query_buffer_size(void)
1863{
1864	return 0;
1865}
1866
1867size_t
1868http2_get_response_buffer_size(void)
1869{
1870	return 0;
1871}
1872
1873void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
1874	struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
1875{
1876}
1877
1878/*********** End of Dummy routines ***********/
1879