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