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