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