]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/fake_event.c
import unbound 1.4.17
[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 LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * 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/ldns-testpkts.h"
61 #include "util/log.h"
62 #include "util/fptr_wlist.h"
63 #include <signal.h>
64 struct worker;
65 struct daemon_remote;
66
67 /** Global variable: the scenario. Saved here for when event_init is done. */
68 static struct replay_scenario* saved_scenario = NULL;
69
70 /** add timers and the values do not overflow or become negative */
71 static void
72 timeval_add(struct timeval* d, const struct timeval* add)
73 {
74 #ifndef S_SPLINT_S
75         d->tv_sec += add->tv_sec;
76         d->tv_usec += add->tv_usec;
77         if(d->tv_usec > 1000000) {
78                 d->tv_usec -= 1000000;
79                 d->tv_sec++;
80         }
81 #endif
82 }
83
84 void 
85 fake_temp_file(const char* adj, const char* id, char* buf, size_t len)
86 {
87 #ifdef USE_WINSOCK
88         snprintf(buf, len, "testbound_%u%s%s.tmp",
89                 (unsigned)getpid(), adj, id);
90 #else
91         snprintf(buf, len, "/tmp/testbound_%u%s%s.tmp",
92                 (unsigned)getpid(), adj, id);
93 #endif
94 }
95
96 void 
97 fake_event_init(struct replay_scenario* scen)
98 {
99         saved_scenario = scen;
100 }
101
102 void 
103 fake_event_cleanup(void)
104 {
105         replay_scenario_delete(saved_scenario);
106         saved_scenario = NULL;
107 }
108
109 /** helper function that logs a ldns_pkt packet to logfile */
110 static void
111 log_pkt(const char* desc, ldns_pkt* pkt)
112 {
113         char* str = ldns_pkt2str(pkt);
114         if(!str)
115                 log_info("%s: (failed)", desc);
116         else {
117                 log_info("%s%s", desc, str);
118                 free(str);
119         }
120 }
121
122 /**
123  * Returns a string describing the event type.
124  */
125 static const char*
126 repevt_string(enum replay_event_type t)
127 {
128         switch(t) {
129         case repevt_nothing:     return "NOTHING";
130         case repevt_front_query: return "QUERY";
131         case repevt_front_reply: return "CHECK_ANSWER";
132         case repevt_timeout:     return "TIMEOUT";
133         case repevt_time_passes: return "TIME_PASSES";
134         case repevt_back_reply:  return "REPLY";
135         case repevt_back_query:  return "CHECK_OUT_QUERY";
136         case repevt_autotrust_check: return "CHECK_AUTOTRUST";
137         case repevt_error:       return "ERROR";
138         case repevt_assign:      return "ASSIGN";
139         case repevt_traffic:     return "TRAFFIC";
140         case repevt_infra_rtt:   return "INFRA_RTT";
141         default:                 return "UNKNOWN";
142         }
143 }
144
145 /** delete a fake pending */
146 static void 
147 delete_fake_pending(struct fake_pending* pend)
148 {
149         if(!pend)
150                 return;
151         free(pend->zone);
152         ldns_buffer_free(pend->buffer);
153         ldns_pkt_free(pend->pkt);
154         free(pend);
155 }
156
157 /** delete a replay answer */
158 static void
159 delete_replay_answer(struct replay_answer* a)
160 {
161         if(!a)
162                 return;
163         if(a->repinfo.c) {
164                 ldns_buffer_free(a->repinfo.c->buffer);
165                 free(a->repinfo.c);
166         }
167         ldns_pkt_free(a->pkt);
168         free(a);
169 }
170
171 /**
172  * return: true if pending query matches the now event.
173  */
174 static int 
175 pending_matches_current(struct replay_runtime* runtime, 
176         struct entry** entry, struct fake_pending **pend)
177 {
178         struct fake_pending* p;
179         struct entry* e;
180         if(!runtime->now || runtime->now->evt_type != repevt_back_query
181                 || !runtime->pending_list)
182                 return 0;
183         /* see if any of the pending queries matches */
184         for(p = runtime->pending_list; p; p = p->next) {
185                 if(runtime->now->addrlen != 0 &&
186                         sockaddr_cmp(&p->addr, p->addrlen, &runtime->now->addr,
187                         runtime->now->addrlen) != 0)
188                         continue;
189                 if((e=find_match(runtime->now->match, p->pkt, p->transport))) {
190                         *entry = e;
191                         *pend = p;
192                         return 1;
193                 }
194         }
195         return 0;
196 }
197
198 /**
199  * Find the range that matches this pending message.
200  * @param runtime: runtime with current moment, and range list.
201  * @param entry: returns the pointer to entry that matches.
202  * @param pend: the pending that the entry must match.
203  * @return: true if a match is found.
204  */
205 static int
206 pending_find_match(struct replay_runtime* runtime, struct entry** entry, 
207         struct fake_pending* pend)
208 {
209         int timenow = runtime->now->time_step;
210         struct replay_range* p = runtime->scenario->range_list;
211         while(p) {
212                 if(p->start_step <= timenow && timenow <= p->end_step &&
213                   (p->addrlen == 0 || sockaddr_cmp(&p->addr, p->addrlen,
214                         &pend->addr, pend->addrlen) == 0) &&
215                   (*entry = find_match(p->match, pend->pkt, pend->transport))) {
216                         log_info("matched query time %d in range [%d, %d] "
217                                 "with entry line %d", timenow, 
218                                 p->start_step, p->end_step, (*entry)->lineno);
219                         if(p->addrlen != 0)
220                                 log_addr(0, "matched ip", &p->addr, p->addrlen);
221                         log_pkt("matched pkt: ", (*entry)->reply_list->reply);
222                         return 1;
223                 }
224                 p = p->next_range;
225         }
226         return 0;
227 }
228
229 /**
230  * See if outgoing pending query matches an entry.
231  * @param runtime: runtime.
232  * @param entry: if true, the entry that matches is returned.
233  * @param pend: if true, the outgoing message that matches is returned.
234  * @return: true if pending query matches the now event.
235  */
236 static int 
237 pending_matches_range(struct replay_runtime* runtime, 
238         struct entry** entry, struct fake_pending** pend)
239 {
240         struct fake_pending* p = runtime->pending_list;
241         /* slow, O(N*N), but it works as advertised with weird matching */
242         while(p) {
243                 log_info("check of pending");
244                 if(pending_find_match(runtime, entry, p)) {
245                         *pend = p;
246                         return 1;
247                 }
248                 p = p->next;
249         }
250         return 0;
251 }
252
253 /**
254  * Remove the item from the pending list.
255  */
256 static void
257 pending_list_delete(struct replay_runtime* runtime, struct fake_pending* pend)
258 {
259         struct fake_pending** prev = &runtime->pending_list;
260         struct fake_pending* p = runtime->pending_list;
261
262         while(p) {
263                 if(p == pend) {
264                         *prev = p->next;
265                         delete_fake_pending(pend);
266                         return;
267                 }
268
269                 prev = &p->next;
270                 p = p->next;
271         }
272 }
273
274 /**
275  * Fill buffer with reply from the entry.
276  */
277 static void
278 fill_buffer_with_reply(ldns_buffer* buffer, struct entry* entry, ldns_pkt* q)
279 {
280         ldns_status status;
281         ldns_pkt* answer_pkt = NULL;
282         log_assert(entry && entry->reply_list);
283         ldns_buffer_clear(buffer);
284         if(entry->reply_list->reply_from_hex) {
285                 status = ldns_buffer2pkt_wire(&answer_pkt, 
286                         entry->reply_list->reply_from_hex);
287                 if(status != LDNS_STATUS_OK) {
288                         log_err("testbound: hex packet unparsable, used asis.");
289                         ldns_buffer_write(buffer, 
290                         ldns_buffer_begin(entry->reply_list->reply_from_hex), 
291                         ldns_buffer_limit(entry->reply_list->reply_from_hex));
292                 }
293         } else {
294                 answer_pkt = ldns_pkt_clone(entry->reply_list->reply);
295         }
296         if(answer_pkt) {
297                 if(q) adjust_packet(entry, answer_pkt, q);
298                 status = ldns_pkt2buffer_wire(buffer, answer_pkt);
299                 if(status != LDNS_STATUS_OK)
300                         fatal_exit("ldns: cannot pkt2buffer_wire parsed pkt");
301         }
302         ldns_pkt_free(answer_pkt);
303         ldns_buffer_flip(buffer);
304 }
305
306 /**
307  * Perform range entry on pending message.
308  * @param runtime: runtime buffer size preference.
309  * @param entry: entry that codes for the reply to do.
310  * @param pend: pending query that is answered, callback called.
311  */
312 static void
313 answer_callback_from_entry(struct replay_runtime* runtime,
314         struct entry* entry, struct fake_pending* pend)
315 {
316         struct comm_point c;
317         struct comm_reply repinfo;
318         void* cb_arg = pend->cb_arg;
319         comm_point_callback_t* cb = pend->callback;
320
321         memset(&c, 0, sizeof(c));
322         c.fd = -1;
323         c.buffer = ldns_buffer_new(runtime->bufsize);
324         c.type = comm_udp;
325         if(pend->transport == transport_tcp)
326                 c.type = comm_tcp;
327         fill_buffer_with_reply(c.buffer, entry, pend->pkt);
328         repinfo.c = &c;
329         repinfo.addrlen = pend->addrlen;
330         memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
331         if(!pend->serviced)
332                 pending_list_delete(runtime, pend);
333         if((*cb)(&c, cb_arg, NETEVENT_NOERROR, &repinfo)) {
334                 fatal_exit("testbound: unexpected: callback returned 1");
335         }
336         ldns_buffer_free(c.buffer);
337 }
338
339 /** Check the now moment answer check event */
340 static void
341 answer_check_it(struct replay_runtime* runtime)
342 {
343         struct replay_answer* ans = runtime->answer_list, 
344                 *prev = NULL;
345         log_assert(runtime && runtime->now && 
346                 runtime->now->evt_type == repevt_front_reply);
347         while(ans) {
348                 enum transport_type tr = transport_tcp;
349                 if(ans->repinfo.c->type == comm_udp)
350                         tr = transport_udp;
351                 if((runtime->now->addrlen == 0 || sockaddr_cmp(
352                         &runtime->now->addr, runtime->now->addrlen,
353                         &ans->repinfo.addr, ans->repinfo.addrlen) == 0) &&
354                         find_match(runtime->now->match, ans->pkt, tr)) {
355                         log_info("testbound matched event entry from line %d",
356                                 runtime->now->match->lineno);
357                         log_info("testbound: do STEP %d %s", 
358                                 runtime->now->time_step,
359                                 repevt_string(runtime->now->evt_type));
360                         if(prev)
361                                 prev->next = ans->next;
362                         else    runtime->answer_list = ans->next;
363                         if(!ans->next)
364                                 runtime->answer_last = prev;
365                         delete_replay_answer(ans);
366                         return;
367                 } else {
368                         prev = ans;
369                         ans = ans->next;
370                 }
371         }
372         log_info("testbound: do STEP %d %s", runtime->now->time_step,
373                 repevt_string(runtime->now->evt_type));
374         fatal_exit("testbound: not matched");
375 }
376
377 /**
378  * Create commpoint (as return address) for a fake incoming query.
379  */
380 static void
381 fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
382 {
383         struct comm_reply repinfo;
384         memset(&repinfo, 0, sizeof(repinfo));
385         repinfo.c = (struct comm_point*)calloc(1, sizeof(struct comm_point));
386         repinfo.addrlen = (socklen_t)sizeof(struct sockaddr_in);
387         if(todo->addrlen != 0) {
388                 repinfo.addrlen = todo->addrlen;
389                 memcpy(&repinfo.addr, &todo->addr, todo->addrlen);
390         }
391         repinfo.c->fd = -1;
392         repinfo.c->ev = (struct internal_event*)runtime;
393         repinfo.c->buffer = ldns_buffer_new(runtime->bufsize);
394         if(todo->match->match_transport == transport_tcp)
395                 repinfo.c->type = comm_tcp;
396         else    repinfo.c->type = comm_udp;
397         fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL);
398         log_info("testbound: incoming QUERY");
399         log_pkt("query pkt", todo->match->reply_list->reply);
400         /* call the callback for incoming queries */
401         if((*runtime->callback_query)(repinfo.c, runtime->cb_arg, 
402                 NETEVENT_NOERROR, &repinfo)) {
403                 /* send immediate reply */
404                 comm_point_send_reply(&repinfo);
405         }
406         /* clear it again, in case copy not done properly */
407         memset(&repinfo, 0, sizeof(repinfo));
408 }
409
410 /**
411  * Perform callback for fake pending message.
412  */
413 static void
414 fake_pending_callback(struct replay_runtime* runtime, 
415         struct replay_moment* todo, int error)
416 {
417         struct fake_pending* p = runtime->pending_list;
418         struct comm_reply repinfo;
419         struct comm_point c;
420         void* cb_arg;
421         comm_point_callback_t* cb;
422
423         memset(&c, 0, sizeof(c));
424         if(!p) fatal_exit("No pending queries.");
425         cb_arg = p->cb_arg;
426         cb = p->callback;
427         log_assert(todo->qname == NULL); /* or find that one */
428         c.buffer = ldns_buffer_new(runtime->bufsize);
429         c.type = comm_udp;
430         if(p->transport == transport_tcp)
431                 c.type = comm_tcp;
432         if(todo->evt_type == repevt_back_reply && todo->match) {
433                 fill_buffer_with_reply(c.buffer, todo->match, p->pkt);
434         }
435         repinfo.c = &c;
436         repinfo.addrlen = p->addrlen;
437         memcpy(&repinfo.addr, &p->addr, p->addrlen);
438         if(!p->serviced)
439                 pending_list_delete(runtime, p);
440         if((*cb)(&c, cb_arg, error, &repinfo)) {
441                 fatal_exit("unexpected: pending callback returned 1");
442         }
443         /* delete the pending item. */
444         ldns_buffer_free(c.buffer);
445 }
446
447 /** pass time */
448 static void
449 moment_assign(struct replay_runtime* runtime, struct replay_moment* mom)
450 {
451         char* value = macro_process(runtime->vars, runtime, mom->string);
452         if(!value)
453                 fatal_exit("could not process macro step %d", mom->time_step);
454         log_info("assign %s = %s", mom->variable, value);
455         if(!macro_assign(runtime->vars, mom->variable, value))
456                 fatal_exit("out of memory storing macro");
457         free(value);
458         if(verbosity >= VERB_ALGO)
459                 macro_print_debug(runtime->vars);
460 }
461
462 /** pass time */
463 static void
464 time_passes(struct replay_runtime* runtime, struct replay_moment* mom)
465 {
466         struct fake_timer *t;
467         struct timeval tv = mom->elapse;
468         if(mom->string) {
469                 char* xp = macro_process(runtime->vars, runtime, mom->string);
470                 double sec;
471                 if(!xp) fatal_exit("could not macro expand %s", mom->string);
472                 verbose(VERB_ALGO, "EVAL %s", mom->string);
473                 sec = atof(xp);
474                 free(xp);
475 #ifndef S_SPLINT_S
476                 tv.tv_sec = sec;
477                 tv.tv_usec = (int)((sec - (double)tv.tv_sec) *1000000. + 0.5);
478 #endif
479         }
480         timeval_add(&runtime->now_tv, &tv);
481         runtime->now_secs = (uint32_t)runtime->now_tv.tv_sec;
482 #ifndef S_SPLINT_S
483         log_info("elapsed %d.%6.6d  now %d.%6.6d", 
484                 (int)tv.tv_sec, (int)tv.tv_usec,
485                 (int)runtime->now_tv.tv_sec, (int)runtime->now_tv.tv_usec);
486 #endif
487         /* see if any timers have fired; and run them */
488         while( (t=replay_get_oldest_timer(runtime)) ) {
489                 t->enabled = 0;
490                 log_info("fake_timer callback");
491                 fptr_ok(fptr_whitelist_comm_timer(t->cb));
492                 (*t->cb)(t->cb_arg);
493         }
494 }
495
496 /** check autotrust file contents */
497 static void
498 autotrust_check(struct replay_runtime* runtime, struct replay_moment* mom)
499 {
500         char name[1024], line[1024];
501         FILE *in;
502         int lineno = 0, oke=1;
503         char* expanded;
504         struct config_strlist* p;
505         line[sizeof(line)-1] = 0;
506         log_assert(mom->autotrust_id);
507         fake_temp_file("_auto_", mom->autotrust_id, name, sizeof(name));
508         in = fopen(name, "r");
509         if(!in) fatal_exit("could not open %s: %s", name, strerror(errno));
510         for(p=mom->file_content; p; p=p->next) {
511                 lineno++;
512                 if(!fgets(line, (int)sizeof(line)-1, in)) {
513                         log_err("autotrust check failed, could not read line");
514                         log_err("file %s, line %d", name, lineno);
515                         log_err("should be: %s", p->str);
516                         fatal_exit("autotrust_check failed");
517                 }
518                 if(line[0]) line[strlen(line)-1] = 0; /* remove newline */
519                 expanded = macro_process(runtime->vars, runtime, p->str);
520                 if(!expanded) 
521                         fatal_exit("could not expand macro line %d", lineno);
522                 if(verbosity >= 7 && strcmp(p->str, expanded) != 0)
523                         log_info("expanded '%s' to '%s'", p->str, expanded);
524                 if(strcmp(expanded, line) != 0) {
525                         log_err("mismatch in file %s, line %d", name, lineno);
526                         log_err("file has : %s", line);
527                         log_err("should be: %s", expanded);
528                         free(expanded);
529                         oke = 0;
530                         continue;
531                 }
532                 free(expanded);
533                 fprintf(stderr, "%s:%2d ok : %s\n", name, lineno, line);
534         }
535         if(fgets(line, (int)sizeof(line)-1, in)) {
536                 log_err("autotrust check failed, extra lines in %s after %d",
537                         name, lineno);
538                 do {
539                         fprintf(stderr, "file has: %s", line);
540                 } while(fgets(line, (int)sizeof(line)-1, in));
541                 oke = 0;
542         }
543         fclose(in);
544         if(!oke)
545                 fatal_exit("autotrust_check STEP %d failed", mom->time_step);
546         log_info("autotrust %s is OK", mom->autotrust_id);
547 }
548
549 /** Store RTT in infra cache */
550 static void
551 do_infra_rtt(struct replay_runtime* runtime)
552 {
553         struct replay_moment* now = runtime->now;
554         int rto;
555         ldns_rdf* dp = ldns_dname_new_frm_str(now->variable);
556         if(!dp) fatal_exit("cannot parse %s", now->variable);
557         rto = infra_rtt_update(runtime->infra, &now->addr,
558                 now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp),
559                 LDNS_RR_TYPE_A, atoi(now->string), -1, runtime->now_secs);
560         log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
561         log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable,
562                 atoi(now->string), rto);
563         if(rto == 0) fatal_exit("infra_rtt_update failed");
564         ldns_rdf_deep_free(dp);
565 }
566
567 /** perform exponential backoff on the timout */
568 static void
569 expon_timeout_backoff(struct replay_runtime* runtime)
570 {
571         struct fake_pending* p = runtime->pending_list;
572         int rtt, vs;
573         uint8_t edns_lame_known;
574         int last_rtt, rto;
575         if(!p) return; /* no pending packet to backoff */
576         if(!infra_host(runtime->infra, &p->addr, p->addrlen, p->zone,
577                 p->zonelen, runtime->now_secs, &vs, &edns_lame_known, &rtt))
578                 return;
579         last_rtt = rtt;
580         rto = infra_rtt_update(runtime->infra, &p->addr, p->addrlen, p->zone,
581                 p->zonelen, p->qtype, -1, last_rtt, runtime->now_secs);
582         log_info("infra_rtt_update returned rto %d", rto);
583 }
584
585 /**
586  * Advance to the next moment.
587  */
588 static void
589 advance_moment(struct replay_runtime* runtime)
590 {
591         if(!runtime->now)
592                 runtime->now = runtime->scenario->mom_first;
593         else    runtime->now = runtime->now->mom_next;
594 }
595
596 /**
597  * Perform actions or checks determined by the moment.
598  * Also advances the time by one step.
599  * @param runtime: scenario runtime information.
600  */
601 static void
602 do_moment_and_advance(struct replay_runtime* runtime)
603 {
604         struct replay_moment* mom;
605         if(!runtime->now) {
606                 advance_moment(runtime);
607                 return;
608         }
609         log_info("testbound: do STEP %d %s", runtime->now->time_step, 
610                 repevt_string(runtime->now->evt_type));
611         switch(runtime->now->evt_type) {
612         case repevt_nothing:
613                 advance_moment(runtime);
614                 break;
615         case repevt_front_query:
616                 /* advance moment before doing the step, so that the next
617                    moment which may check some result of the mom step
618                    can catch those results. */
619                 mom = runtime->now;
620                 advance_moment(runtime);
621                 fake_front_query(runtime, mom);
622                 break;
623         case repevt_front_reply:
624                 if(runtime->answer_list) 
625                         log_err("testbound: There are unmatched answers.");
626                 fatal_exit("testbound: query answer not matched");
627                 break;
628         case repevt_timeout:
629                 mom = runtime->now;
630                 advance_moment(runtime);
631                 expon_timeout_backoff(runtime);
632                 fake_pending_callback(runtime, mom, NETEVENT_TIMEOUT);
633                 break;
634         case repevt_back_reply:
635                 mom = runtime->now;
636                 advance_moment(runtime);
637                 fake_pending_callback(runtime, mom, NETEVENT_NOERROR);
638                 break;
639         case repevt_back_query:
640                 /* Back queries are matched when they are sent out. */
641                 log_err("No query matching the current moment was sent.");
642                 fatal_exit("testbound: back query not matched");
643                 break;
644         case repevt_error:
645                 mom = runtime->now;
646                 advance_moment(runtime);
647                 fake_pending_callback(runtime, mom, NETEVENT_CLOSED);
648                 break;
649         case repevt_time_passes:
650                 time_passes(runtime, runtime->now);
651                 advance_moment(runtime);
652                 break;
653         case repevt_autotrust_check:
654                 autotrust_check(runtime, runtime->now);
655                 advance_moment(runtime);
656                 break;
657         case repevt_assign:
658                 moment_assign(runtime, runtime->now);
659                 advance_moment(runtime);
660                 break;
661         case repevt_traffic:
662                 advance_moment(runtime);
663                 break;
664         case repevt_infra_rtt:
665                 do_infra_rtt(runtime);
666                 advance_moment(runtime);
667                 break;
668         default:
669                 fatal_exit("testbound: unknown event type %d", 
670                         runtime->now->evt_type);
671         }
672 }
673
674 /** run the scenario in event callbacks */
675 static void
676 run_scenario(struct replay_runtime* runtime)
677 {
678         struct entry* entry = NULL;
679         struct fake_pending* pending = NULL;
680         int max_rounds = 5000;
681         int rounds = 0;
682         runtime->now = runtime->scenario->mom_first;
683         log_info("testbound: entering fake runloop");
684         do {
685                 /* if moment matches pending query do it. */
686                 /* else if moment matches given answer, do it */
687                 /* else if precoded_range matches pending, do it */
688                 /* else do the current moment */
689                 if(pending_matches_current(runtime, &entry, &pending)) {
690                         log_info("testbound: do STEP %d CHECK_OUT_QUERY", 
691                                 runtime->now->time_step);
692                         advance_moment(runtime);
693                         if(entry->copy_id)
694                                 answer_callback_from_entry(runtime, entry, 
695                                 pending);
696                 } else if(runtime->answer_list && runtime->now && 
697                         runtime->now->evt_type == repevt_front_reply) {
698                         answer_check_it(runtime);                       
699                         advance_moment(runtime);
700                 } else if(pending_matches_range(runtime, &entry, &pending)) {
701                         answer_callback_from_entry(runtime, entry, pending);
702                 } else {
703                         do_moment_and_advance(runtime);
704                 }
705                 log_info("testbound: end of event stage");
706                 rounds++;
707                 if(rounds > max_rounds)
708                         fatal_exit("testbound: too many rounds, it loops.");
709         } while(runtime->now);
710
711         if(runtime->pending_list) {
712                 struct fake_pending* p;
713                 log_err("testbound: there are still messages pending.");
714                 for(p = runtime->pending_list; p; p=p->next) {
715                         log_pkt("pending msg", p->pkt);
716                         log_addr(0, "pending to", &p->addr, p->addrlen);
717                 }
718                 fatal_exit("testbound: there are still messages pending.");
719         }
720         if(runtime->answer_list) {
721                 fatal_exit("testbound: there are unmatched answers.");
722         }
723         log_info("testbound: exiting fake runloop.");
724         runtime->exit_cleanly = 1;
725 }
726
727 /*********** Dummy routines ***********/
728
729 struct listen_dnsport* 
730 listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
731         size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
732         void* ATTR_UNUSED(sslctx), comm_point_callback_t* cb, void* cb_arg)
733 {
734         struct replay_runtime* runtime = (struct replay_runtime*)base;
735         struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport));
736         if(!l)
737                 return NULL;
738         l->base = base;
739         l->udp_buff = ldns_buffer_new(bufsize);
740         if(!l->udp_buff) {
741                 free(l);
742                 return NULL;
743         }
744         runtime->callback_query = cb;
745         runtime->cb_arg = cb_arg;
746         runtime->bufsize = bufsize;
747         return l;
748 }
749
750 void 
751 listen_delete(struct listen_dnsport* listen)
752 {
753         if(!listen)
754                 return;
755         ldns_buffer_free(listen->udp_buff);
756         free(listen);
757 }
758
759 struct comm_base* 
760 comm_base_create(int ATTR_UNUSED(sigs))
761 {
762         /* we return the runtime structure instead. */
763         struct replay_runtime* runtime = (struct replay_runtime*)
764                 calloc(1, sizeof(struct replay_runtime));
765         runtime->scenario = saved_scenario;
766         runtime->vars = macro_store_create();
767         if(!runtime->vars) fatal_exit("out of memory");
768         return (struct comm_base*)runtime;
769 }
770
771 void 
772 comm_base_delete(struct comm_base* b)
773 {
774         struct replay_runtime* runtime = (struct replay_runtime*)b;
775         struct fake_pending* p, *np;
776         struct replay_answer* a, *na;
777         struct fake_timer* t, *nt;
778         if(!runtime)
779                 return;
780         runtime->scenario= NULL;
781         p = runtime->pending_list;
782         while(p) {
783                 np = p->next;
784                 delete_fake_pending(p);
785                 p = np;
786         }
787         a = runtime->answer_list;
788         while(a) {
789                 na = a->next;
790                 delete_replay_answer(a);
791                 a = na;
792         }
793         t = runtime->timer_list;
794         while(t) {
795                 nt = t->next;
796                 free(t);
797                 t = nt;
798         }
799         macro_store_delete(runtime->vars);
800         free(runtime);
801 }
802
803 void
804 comm_base_timept(struct comm_base* b, uint32_t** tt, struct timeval** tv)
805 {
806         struct replay_runtime* runtime = (struct replay_runtime*)b;
807         *tt = &runtime->now_secs;
808         *tv = &runtime->now_tv;
809 }
810
811 void 
812 comm_base_dispatch(struct comm_base* b)
813 {
814         struct replay_runtime* runtime = (struct replay_runtime*)b;
815         run_scenario(runtime);
816         if(runtime->sig_cb)
817                 (*runtime->sig_cb)(SIGTERM, runtime->sig_cb_arg);
818         else    exit(0); /* OK exit when LIBEVENT_SIGNAL_PROBLEM exists */
819 }
820
821 void 
822 comm_base_exit(struct comm_base* b)
823 {
824         struct replay_runtime* runtime = (struct replay_runtime*)b;
825         if(!runtime->exit_cleanly) {
826                 /* some sort of failure */
827                 fatal_exit("testbound: comm_base_exit was called.");
828         }
829 }
830
831 struct comm_signal* 
832 comm_signal_create(struct comm_base* base,
833         void (*callback)(int, void*), void* cb_arg)
834 {
835         struct replay_runtime* runtime = (struct replay_runtime*)base;
836         runtime->sig_cb = callback;
837         runtime->sig_cb_arg = cb_arg;
838         return calloc(1, sizeof(struct comm_signal));
839 }
840
841 int 
842 comm_signal_bind(struct comm_signal* ATTR_UNUSED(comsig), int 
843         ATTR_UNUSED(sig))
844 {
845         return 1;
846 }
847
848 void 
849 comm_signal_delete(struct comm_signal* comsig)
850 {
851         free(comsig);
852 }
853
854 void 
855 comm_point_send_reply(struct comm_reply* repinfo)
856 {
857         struct replay_answer* ans = (struct replay_answer*)calloc(1,
858                 sizeof(struct replay_answer));
859         ldns_status status;
860         struct replay_runtime* runtime = (struct replay_runtime*)repinfo->c->ev;
861         log_info("testbound: comm_point_send_reply fake");
862         /* dump it into the todo list */
863         log_assert(ans);
864         memcpy(&ans->repinfo, repinfo, sizeof(struct comm_reply));
865         ans->next = NULL;
866         if(runtime->answer_last)
867                 runtime->answer_last->next = ans;
868         else    runtime->answer_list = ans;
869         runtime->answer_last = ans;
870
871         /* try to parse packet */
872         status = ldns_buffer2pkt_wire(&ans->pkt, ans->repinfo.c->buffer);
873         if(status != LDNS_STATUS_OK) {
874                 log_err("ldns error parsing packet: %s",
875                         ldns_get_errorstr_by_id(status));
876                 fatal_exit("Sending unparseable DNS replies to clients!");
877         }
878         log_pkt("reply pkt: ", ans->pkt);
879 }
880
881 void 
882 comm_point_drop_reply(struct comm_reply* repinfo)
883 {
884         log_info("comm_point_drop_reply fake");
885         if(repinfo->c) {
886                 ldns_buffer_free(repinfo->c->buffer);
887                 free(repinfo->c);
888         }
889 }
890
891 struct outside_network* 
892 outside_network_create(struct comm_base* base, size_t bufsize, 
893         size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs), 
894         int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4), 
895         int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp), 
896         struct infra_cache* infra,
897         struct ub_randstate* ATTR_UNUSED(rnd), 
898         int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
899         int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
900         void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
901         int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx))
902 {
903         struct replay_runtime* runtime = (struct replay_runtime*)base;
904         struct outside_network* outnet =  calloc(1, 
905                 sizeof(struct outside_network));
906         (void)unwanted_action;
907         if(!outnet)
908                 return NULL;
909         runtime->infra = infra;
910         outnet->base = base;
911         outnet->udp_buff = ldns_buffer_new(bufsize);
912         if(!outnet->udp_buff)
913                 return NULL;
914         return outnet;
915 }
916
917 void 
918 outside_network_delete(struct outside_network* outnet)
919 {
920         if(!outnet)
921                 return;
922         ldns_buffer_free(outnet->udp_buff);
923         free(outnet);
924 }
925
926 void 
927 outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet))
928 {
929 }
930
931 struct pending* 
932 pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
933         struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
934         comm_point_callback_t* callback, void* callback_arg)
935 {
936         struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
937         struct fake_pending* pend = (struct fake_pending*)calloc(1,
938                 sizeof(struct fake_pending));
939         ldns_status status;
940         log_assert(pend);
941         pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
942         log_assert(pend->buffer);
943         ldns_buffer_write(pend->buffer, ldns_buffer_begin(packet),
944                 ldns_buffer_limit(packet));
945         ldns_buffer_flip(pend->buffer);
946         memcpy(&pend->addr, addr, addrlen);
947         pend->addrlen = addrlen;
948         pend->callback = callback;
949         pend->cb_arg = callback_arg;
950         pend->timeout = timeout/1000;
951         pend->transport = transport_udp;
952         pend->pkt = NULL;
953         pend->zone = NULL;
954         pend->serviced = 0;
955         pend->runtime = runtime;
956         status = ldns_buffer2pkt_wire(&pend->pkt, packet);
957         if(status != LDNS_STATUS_OK) {
958                 log_err("ldns error parsing udp output packet: %s",
959                         ldns_get_errorstr_by_id(status));
960                 fatal_exit("Sending unparseable DNS packets to servers!");
961         }
962         log_pkt("pending udp pkt: ", pend->pkt);
963
964         /* see if it matches the current moment */
965         if(runtime->now && runtime->now->evt_type == repevt_back_query &&
966                 (runtime->now->addrlen == 0 || sockaddr_cmp(
967                         &runtime->now->addr, runtime->now->addrlen,
968                         &pend->addr, pend->addrlen) == 0) &&
969                 find_match(runtime->now->match, pend->pkt, pend->transport)) {
970                 log_info("testbound: matched pending to event. "
971                         "advance time between events.");
972                 log_info("testbound: do STEP %d %s", runtime->now->time_step,
973                         repevt_string(runtime->now->evt_type));
974                 advance_moment(runtime);
975                 /* still create the pending, because we need it to callback */
976         } 
977         log_info("testbound: created fake pending");
978         /* add to list */
979         pend->next = runtime->pending_list;
980         runtime->pending_list = pend;
981         return (struct pending*)pend;
982 }
983
984 struct waiting_tcp* 
985 pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
986         struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
987         comm_point_callback_t* callback, void* callback_arg,
988         int ATTR_UNUSED(ssl_upstream))
989 {
990         struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
991         struct fake_pending* pend = (struct fake_pending*)calloc(1,
992                 sizeof(struct fake_pending));
993         ldns_status status;
994         log_assert(pend);
995         pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
996         log_assert(pend->buffer);
997         ldns_buffer_write(pend->buffer, ldns_buffer_begin(packet),
998                 ldns_buffer_limit(packet));
999         ldns_buffer_flip(pend->buffer);
1000         memcpy(&pend->addr, addr, addrlen);
1001         pend->addrlen = addrlen;
1002         pend->callback = callback;
1003         pend->cb_arg = callback_arg;
1004         pend->timeout = timeout;
1005         pend->transport = transport_tcp;
1006         pend->pkt = NULL;
1007         pend->zone = NULL;
1008         pend->runtime = runtime;
1009         pend->serviced = 0;
1010         status = ldns_buffer2pkt_wire(&pend->pkt, packet);
1011         if(status != LDNS_STATUS_OK) {
1012                 log_err("ldns error parsing tcp output packet: %s",
1013                         ldns_get_errorstr_by_id(status));
1014                 fatal_exit("Sending unparseable DNS packets to servers!");
1015         }
1016         log_pkt("pending tcp pkt: ", pend->pkt);
1017
1018         /* see if it matches the current moment */
1019         if(runtime->now && runtime->now->evt_type == repevt_back_query &&
1020                 (runtime->now->addrlen == 0 || sockaddr_cmp(
1021                         &runtime->now->addr, runtime->now->addrlen,
1022                         &pend->addr, pend->addrlen) == 0) &&
1023                 find_match(runtime->now->match, pend->pkt, pend->transport)) {
1024                 log_info("testbound: matched pending to event. "
1025                         "advance time between events.");
1026                 log_info("testbound: do STEP %d %s", runtime->now->time_step,
1027                         repevt_string(runtime->now->evt_type));
1028                 advance_moment(runtime);
1029                 /* still create the pending, because we need it to callback */
1030         } 
1031         log_info("testbound: created fake pending");
1032         /* add to list */
1033         pend->next = runtime->pending_list;
1034         runtime->pending_list = pend;
1035         return (struct waiting_tcp*)pend;
1036 }
1037
1038 struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
1039         uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
1040         uint16_t flags, int dnssec, int ATTR_UNUSED(want_dnssec),
1041         int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
1042         struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
1043         size_t zonelen, comm_point_callback_t* callback, void* callback_arg,
1044         ldns_buffer* ATTR_UNUSED(buff), int (*arg_compare)(void*,void*))
1045 {
1046         struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
1047         struct fake_pending* pend = (struct fake_pending*)calloc(1,
1048                 sizeof(struct fake_pending));
1049         char z[256];
1050         ldns_status status;
1051         (void)arg_compare;
1052         log_assert(pend);
1053         log_nametypeclass(VERB_OPS, "pending serviced query", 
1054                 qname, qtype, qclass);
1055         dname_str(zone, z);
1056         verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s", 
1057                 z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"",
1058                 (flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":"");
1059
1060         /* create packet with EDNS */
1061         pend->buffer = ldns_buffer_new(512);
1062         log_assert(pend->buffer);
1063         ldns_buffer_write_u16(pend->buffer, 0); /* id */
1064         ldns_buffer_write_u16(pend->buffer, flags);
1065         ldns_buffer_write_u16(pend->buffer, 1); /* qdcount */
1066         ldns_buffer_write_u16(pend->buffer, 0); /* ancount */
1067         ldns_buffer_write_u16(pend->buffer, 0); /* nscount */
1068         ldns_buffer_write_u16(pend->buffer, 0); /* arcount */
1069         ldns_buffer_write(pend->buffer, qname, qnamelen);
1070         ldns_buffer_write_u16(pend->buffer, qtype);
1071         ldns_buffer_write_u16(pend->buffer, qclass);
1072         ldns_buffer_flip(pend->buffer);
1073         if(1) {
1074                 /* add edns */
1075                 struct edns_data edns;
1076                 edns.edns_present = 1;
1077                 edns.ext_rcode = 0;
1078                 edns.edns_version = EDNS_ADVERTISED_VERSION;
1079                 edns.udp_size = EDNS_ADVERTISED_SIZE;
1080                 edns.bits = 0;
1081                 if(dnssec)
1082                         edns.bits = EDNS_DO;
1083                 attach_edns_record(pend->buffer, &edns);
1084         }
1085         memcpy(&pend->addr, addr, addrlen);
1086         pend->addrlen = addrlen;
1087         pend->zone = memdup(zone, zonelen);
1088         pend->zonelen = zonelen;
1089         pend->qtype = (int)qtype;
1090         log_assert(pend->zone);
1091         pend->callback = callback;
1092         pend->cb_arg = callback_arg;
1093         pend->timeout = UDP_AUTH_QUERY_TIMEOUT;
1094         pend->transport = transport_udp; /* pretend UDP */
1095         pend->pkt = NULL;
1096         pend->runtime = runtime;
1097         pend->serviced = 1;
1098         status = ldns_buffer2pkt_wire(&pend->pkt, pend->buffer);
1099         if(status != LDNS_STATUS_OK) {
1100                 log_err("ldns error parsing serviced output packet: %s",
1101                         ldns_get_errorstr_by_id(status));
1102                 fatal_exit("internal error");
1103         }
1104         /*log_pkt("pending serviced query: ", pend->pkt);*/
1105
1106         /* see if it matches the current moment */
1107         if(runtime->now && runtime->now->evt_type == repevt_back_query &&
1108                 (runtime->now->addrlen == 0 || sockaddr_cmp(
1109                         &runtime->now->addr, runtime->now->addrlen,
1110                         &pend->addr, pend->addrlen) == 0) &&
1111                 find_match(runtime->now->match, pend->pkt, pend->transport)) {
1112                 log_info("testbound: matched pending to event. "
1113                         "advance time between events.");
1114                 log_info("testbound: do STEP %d %s", runtime->now->time_step,
1115                         repevt_string(runtime->now->evt_type));
1116                 advance_moment(runtime);
1117                 /* still create the pending, because we need it to callback */
1118         } 
1119         log_info("testbound: created fake pending");
1120         /* add to list */
1121         pend->next = runtime->pending_list;
1122         runtime->pending_list = pend;
1123         return (struct serviced_query*)pend;
1124 }
1125
1126 void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
1127 {
1128         struct fake_pending* pend = (struct fake_pending*)sq;
1129         struct replay_runtime* runtime = pend->runtime;
1130         /* delete from the list */
1131         struct fake_pending* p = runtime->pending_list, *prev=NULL;
1132         while(p) {
1133                 if(p == pend) {
1134                         log_assert(p->cb_arg == cb_arg);
1135                         log_info("serviced pending delete");
1136                         if(prev)
1137                                 prev->next = p->next;
1138                         else    runtime->pending_list = p->next;
1139                         ldns_buffer_free(p->buffer);
1140                         ldns_pkt_free(p->pkt);
1141                         free(p->zone);
1142                         free(p);
1143                         return;
1144                 }
1145                 prev = p;
1146                 p = p->next;
1147         }
1148         log_info("double delete of pending serviced query");
1149 }
1150
1151 struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg))
1152 {
1153         return calloc(1, 1);
1154 }
1155
1156 void listening_ports_free(struct listen_port* list)
1157 {
1158         free(list);
1159 }
1160
1161 struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
1162         int ATTR_UNUSED(fd), size_t ATTR_UNUSED(bufsize),
1163         comm_point_callback_t* ATTR_UNUSED(callback), 
1164         void* ATTR_UNUSED(callback_arg))
1165 {
1166         return calloc(1, 1);
1167 }
1168
1169 struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base),
1170         int ATTR_UNUSED(fd), int ATTR_UNUSED(writing),
1171         comm_point_callback_t* ATTR_UNUSED(callback), 
1172         void* ATTR_UNUSED(callback_arg))
1173 {
1174         /* no pipe comm possible */
1175         return calloc(1, 1);
1176 }
1177
1178 void comm_point_start_listening(struct comm_point* ATTR_UNUSED(c), 
1179         int ATTR_UNUSED(newfd), int ATTR_UNUSED(sec))
1180 {
1181         /* no bg write pipe comm possible */
1182 }
1183
1184 void comm_point_stop_listening(struct comm_point* ATTR_UNUSED(c))
1185 {
1186         /* no bg write pipe comm possible */
1187 }
1188
1189 /* only cmd com _local gets deleted */
1190 void comm_point_delete(struct comm_point* c)
1191 {
1192         free(c);
1193 }
1194
1195 size_t listen_get_mem(struct listen_dnsport* ATTR_UNUSED(listen))
1196 {
1197         return 0;
1198 }
1199
1200 size_t outnet_get_mem(struct outside_network* ATTR_UNUSED(outnet))
1201 {
1202         return 0;
1203 }
1204
1205 size_t comm_point_get_mem(struct comm_point* ATTR_UNUSED(c))
1206 {
1207         return 0;
1208 }
1209
1210 size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c))
1211 {
1212         return 0;
1213 }
1214
1215 /* fake for fptr wlist */
1216 int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c), 
1217         void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1218         struct comm_reply *ATTR_UNUSED(reply_info))
1219 {
1220         log_assert(0);
1221         return 0;
1222 }
1223
1224 int outnet_tcp_cb(struct comm_point* ATTR_UNUSED(c), 
1225         void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1226         struct comm_reply *ATTR_UNUSED(reply_info))
1227 {
1228         log_assert(0);
1229         return 0;
1230 }
1231
1232 void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
1233 {
1234         log_assert(0);
1235 }
1236
1237 void outnet_tcptimer(void* ATTR_UNUSED(arg))
1238 {
1239         log_assert(0);
1240 }
1241
1242 void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), 
1243         void* ATTR_UNUSED(arg))
1244 {
1245         log_assert(0);
1246 }
1247
1248 void comm_point_udp_ancil_callback(int ATTR_UNUSED(fd), 
1249         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1250 {
1251         log_assert(0);
1252 }
1253
1254 void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd), 
1255         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1256 {
1257         log_assert(0);
1258 }
1259
1260 void comm_point_tcp_handle_callback(int ATTR_UNUSED(fd), 
1261         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1262 {
1263         log_assert(0);
1264 }
1265
1266 void comm_timer_callback(int ATTR_UNUSED(fd), 
1267         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1268 {
1269         log_assert(0);
1270 }
1271
1272 void comm_signal_callback(int ATTR_UNUSED(fd), 
1273         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1274 {
1275         log_assert(0);
1276 }
1277
1278 void comm_point_local_handle_callback(int ATTR_UNUSED(fd), 
1279         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1280 {
1281         log_assert(0);
1282 }
1283
1284 void comm_point_raw_handle_callback(int ATTR_UNUSED(fd), 
1285         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1286 {
1287         log_assert(0);
1288 }
1289
1290 void comm_base_handle_slow_accept(int ATTR_UNUSED(fd), 
1291         short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
1292 {
1293         log_assert(0);
1294 }
1295
1296 int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c), 
1297         void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1298         struct comm_reply* ATTR_UNUSED(reply_info))
1299 {
1300         log_assert(0);
1301         return 0;
1302 }
1303
1304 int serviced_tcp_callback(struct comm_point* ATTR_UNUSED(c), 
1305         void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1306         struct comm_reply* ATTR_UNUSED(reply_info))
1307 {
1308         log_assert(0);
1309         return 0;
1310 }
1311
1312 int pending_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1313 {
1314         log_assert(0);
1315         return 0;
1316 }
1317
1318 int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1319 {
1320         log_assert(0);
1321         return 0;
1322 }
1323
1324 /* timers in testbound for autotrust. statistics tested in tpkg. */
1325 struct comm_timer* comm_timer_create(struct comm_base* base, 
1326         void (*cb)(void*), void* cb_arg)
1327 {
1328         struct replay_runtime* runtime = (struct replay_runtime*)base;
1329         struct fake_timer* t = (struct fake_timer*)calloc(1, sizeof(*t));
1330         t->cb = cb;
1331         t->cb_arg = cb_arg;
1332         fptr_ok(fptr_whitelist_comm_timer(t->cb)); /* check in advance */
1333         t->runtime = runtime;
1334         t->next = runtime->timer_list;
1335         runtime->timer_list = t;
1336         return (struct comm_timer*)t;
1337 }
1338
1339 void comm_timer_disable(struct comm_timer* timer)
1340 {
1341         struct fake_timer* t = (struct fake_timer*)timer;
1342         log_info("fake timer disabled");
1343         t->enabled = 0;
1344 }
1345
1346 void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
1347 {
1348         struct fake_timer* t = (struct fake_timer*)timer;
1349         t->enabled = 1;
1350         t->tv = *tv;
1351         log_info("fake timer set %d.%6.6d", 
1352                 (int)t->tv.tv_sec, (int)t->tv.tv_usec);
1353         timeval_add(&t->tv, &t->runtime->now_tv);
1354 }
1355
1356 void comm_timer_delete(struct comm_timer* timer)
1357 {
1358         struct fake_timer* t = (struct fake_timer*)timer;
1359         struct fake_timer** pp, *p;
1360         if(!t) return;
1361
1362         /* remove from linked list */
1363         pp = &t->runtime->timer_list;
1364         p = t->runtime->timer_list;
1365         while(p) {
1366                 if(p == t) {
1367                         /* snip from list */
1368                         *pp = p->next;
1369                         break;
1370                 }
1371                 pp = &p->next;
1372                 p = p->next;
1373         }
1374
1375         free(timer);
1376 }
1377
1378 void comm_base_set_slow_accept_handlers(struct comm_base* ATTR_UNUSED(b),
1379         void (*stop_acc)(void*), void (*start_acc)(void*),
1380         void* ATTR_UNUSED(arg))
1381 {
1382         /* ignore this */
1383         (void)stop_acc;
1384         (void)start_acc;
1385 }
1386
1387 struct event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
1388 {
1389         /* no pipe comm possible in testbound */
1390         return NULL;
1391 }
1392
1393 void daemon_remote_exec(struct worker* ATTR_UNUSED(worker))
1394 {
1395 }
1396
1397 void listen_start_accept(struct listen_dnsport* ATTR_UNUSED(listen))
1398 {
1399 }
1400
1401 void listen_stop_accept(struct listen_dnsport* ATTR_UNUSED(listen))
1402 {
1403 }
1404
1405 void daemon_remote_start_accept(struct daemon_remote* ATTR_UNUSED(rc))
1406 {
1407 }
1408
1409 void daemon_remote_stop_accept(struct daemon_remote* ATTR_UNUSED(rc))
1410 {
1411 }
1412
1413 /*********** End of Dummy routines ***********/