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