]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/fake_event.c
Apply upstream fix 08968baec1122a58bb90d8f97ad948a75f8a5d69:
[FreeBSD/FreeBSD.git] / testcode / fake_event.c
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>
68 struct worker;
69 struct 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 */
74 struct 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. */
95 static struct replay_scenario* saved_scenario = NULL;
96
97 /** add timers and the values do not overflow or become negative */
98 static void
99 timeval_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
111 void 
112 fake_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
123 void 
124 fake_event_init(struct replay_scenario* scen)
125 {
126         saved_scenario = scen;
127 }
128
129 void 
130 fake_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 */
137 static void
138 log_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  */
152 static const char*
153 repevt_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 */
174 static void 
175 delete_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 */
186 static void
187 delete_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  */
202 static int 
203 pending_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  */
234 static int
235 pending_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  */
268 static int 
269 pending_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  */
292 static void
293 pending_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 */
311 static int
312 count_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  */
326 static void
327 fill_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  */
365 static void
366 answer_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 */
404 static void
405 answer_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  */
447 static void
448 fake_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  */
484 static void
485 fake_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 */
529 static void
530 moment_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 */
544 static void
545 time_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 */
578 static void
579 autotrust_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 */
631 static void
632 tempfile_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 */
684 static void
685 do_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 */
703 static void
704 expon_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  */
723 static void
724 advance_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  */
736 static void
737 do_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 */
814 static void
815 run_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
868 struct listen_dnsport* 
869 listen_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
896 void 
897 listen_delete(struct listen_dnsport* listen)
898 {
899         if(!listen)
900                 return;
901         sldns_buffer_free(listen->udp_buff);
902         free(listen);
903 }
904
905 struct comm_base* 
906 comm_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
917 void 
918 comm_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
949 void
950 comm_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
957 void 
958 comm_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
967 void 
968 comm_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
977 struct comm_signal* 
978 comm_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
987 int 
988 comm_signal_bind(struct comm_signal* ATTR_UNUSED(comsig), int 
989         ATTR_UNUSED(sig))
990 {
991         return 1;
992 }
993
994 void 
995 comm_signal_delete(struct comm_signal* comsig)
996 {
997         free(comsig);
998 }
999
1000 void 
1001 comm_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
1024 void 
1025 comm_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
1034 struct outside_network* 
1035 outside_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
1066 void 
1067 outside_network_delete(struct outside_network* outnet)
1068 {
1069         if(!outnet)
1070                 return;
1071         sldns_buffer_free(outnet->udp_buff);
1072         free(outnet);
1073 }
1074
1075 void 
1076 outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
1077 {
1078 }
1079
1080 struct pending* 
1081 pending_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
1130 struct waiting_tcp*
1131 pending_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
1180 struct 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
1281 void 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
1307 int 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
1313 struct 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
1320 void listening_ports_free(struct listen_port* list)
1321 {
1322         free(list);
1323 }
1324
1325 struct 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
1337 struct 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
1350 void 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
1356 void 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 */
1362 void 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
1374 size_t listen_get_mem(struct listen_dnsport* ATTR_UNUSED(listen))
1375 {
1376         return 0;
1377 }
1378
1379 size_t outnet_get_mem(struct outside_network* ATTR_UNUSED(outnet))
1380 {
1381         return 0;
1382 }
1383
1384 size_t comm_point_get_mem(struct comm_point* ATTR_UNUSED(c))
1385 {
1386         return 0;
1387 }
1388
1389 size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c))
1390 {
1391         return 0;
1392 }
1393
1394 /* fake for fptr wlist */
1395 int 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
1403 int 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
1411 void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
1412 {
1413         log_assert(0);
1414 }
1415
1416 void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg))
1417 {
1418         log_assert(0);
1419 }
1420
1421 void outnet_tcptimer(void* ATTR_UNUSED(arg))
1422 {
1423         log_assert(0);
1424 }
1425
1426 void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), 
1427         void* ATTR_UNUSED(arg))
1428 {
1429         log_assert(0);
1430 }
1431
1432 void 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
1438 void 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
1444 void 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
1450 void comm_timer_callback(int ATTR_UNUSED(fd), 
1451         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1452 {
1453         log_assert(0);
1454 }
1455
1456 void comm_signal_callback(int ATTR_UNUSED(fd), 
1457         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1458 {
1459         log_assert(0);
1460 }
1461
1462 void 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
1468 void 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
1474 void 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
1480 void 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
1486 int 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
1494 int 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
1502 int pending_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1503 {
1504         log_assert(0);
1505         return 0;
1506 }
1507
1508 int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1509 {
1510         log_assert(0);
1511         return 0;
1512 }
1513
1514 int reuse_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1515 {
1516         log_assert(0);
1517         return 0;
1518 }
1519
1520 int 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. */
1527 struct 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
1541 void 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
1548 void 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
1558 void 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
1580 void 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
1589 struct 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
1595 void daemon_remote_exec(struct worker* ATTR_UNUSED(worker))
1596 {
1597 }
1598
1599 void listen_start_accept(struct listen_dnsport* ATTR_UNUSED(listen))
1600 {
1601 }
1602
1603 void listen_stop_accept(struct listen_dnsport* ATTR_UNUSED(listen))
1604 {
1605 }
1606
1607 void daemon_remote_start_accept(struct daemon_remote* ATTR_UNUSED(rc))
1608 {
1609 }
1610
1611 void daemon_remote_stop_accept(struct daemon_remote* ATTR_UNUSED(rc))
1612 {
1613 }
1614
1615 int 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
1627 struct 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
1636 struct 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
1645 struct 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
1664 struct 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
1737 struct 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
1767 int 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
1827 int 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
1834 int 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
1841 int 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
1848 void
1849 tcp_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
1855 size_t
1856 tcp_req_info_get_stream_buffer_size(void)
1857 {
1858         return 0;
1859 }
1860
1861 size_t
1862 http2_get_query_buffer_size(void)
1863 {
1864         return 0;
1865 }
1866
1867 size_t
1868 http2_get_response_buffer_size(void)
1869 {
1870         return 0;
1871 }
1872
1873 void 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 ***********/