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 ***********/ 1827