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(sslctx), struct dt_env* ATTR_UNUSED(dtenv), 942 comm_point_callback_type* cb, void *cb_arg) 943 { 944 struct replay_runtime* runtime = (struct replay_runtime*)base; 945 struct listen_dnsport* l= calloc(1, sizeof(struct listen_dnsport)); 946 if(!l) 947 return NULL; 948 l->base = base; 949 l->udp_buff = sldns_buffer_new(bufsize); 950 if(!l->udp_buff) { 951 free(l); 952 return NULL; 953 } 954 runtime->callback_query = cb; 955 runtime->cb_arg = cb_arg; 956 runtime->bufsize = bufsize; 957 return l; 958 } 959 960 void 961 listen_delete(struct listen_dnsport* listen) 962 { 963 if(!listen) 964 return; 965 sldns_buffer_free(listen->udp_buff); 966 free(listen); 967 } 968 969 struct comm_base* 970 comm_base_create(int ATTR_UNUSED(sigs)) 971 { 972 /* we return the runtime structure instead. */ 973 struct replay_runtime* runtime = (struct replay_runtime*) 974 calloc(1, sizeof(struct replay_runtime)); 975 if(!runtime) 976 fatal_exit("out of memory in fake_event.c:comm_base_create"); 977 runtime->scenario = saved_scenario; 978 runtime->vars = macro_store_create(); 979 if(!runtime->vars) fatal_exit("out of memory"); 980 return (struct comm_base*)runtime; 981 } 982 983 void 984 comm_base_delete(struct comm_base* b) 985 { 986 struct replay_runtime* runtime = (struct replay_runtime*)b; 987 struct fake_pending* p, *np; 988 struct replay_answer* a, *na; 989 struct fake_timer* t, *nt; 990 if(!runtime) 991 return; 992 runtime->scenario= NULL; 993 p = runtime->pending_list; 994 while(p) { 995 np = p->next; 996 delete_fake_pending(p); 997 p = np; 998 } 999 a = runtime->answer_list; 1000 while(a) { 1001 na = a->next; 1002 delete_replay_answer(a); 1003 a = na; 1004 } 1005 t = runtime->timer_list; 1006 while(t) { 1007 nt = t->next; 1008 free(t); 1009 t = nt; 1010 } 1011 macro_store_delete(runtime->vars); 1012 free(runtime); 1013 } 1014 1015 void 1016 comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv) 1017 { 1018 struct replay_runtime* runtime = (struct replay_runtime*)b; 1019 *tt = &runtime->now_secs; 1020 *tv = &runtime->now_tv; 1021 } 1022 1023 void 1024 comm_base_dispatch(struct comm_base* b) 1025 { 1026 struct replay_runtime* runtime = (struct replay_runtime*)b; 1027 run_scenario(runtime); 1028 if(runtime->sig_cb) 1029 (*runtime->sig_cb)(SIGTERM, runtime->sig_cb_arg); 1030 else exit(0); /* OK exit when LIBEVENT_SIGNAL_PROBLEM exists */ 1031 } 1032 1033 void 1034 comm_base_exit(struct comm_base* b) 1035 { 1036 struct replay_runtime* runtime = (struct replay_runtime*)b; 1037 if(!runtime->exit_cleanly) { 1038 /* some sort of failure */ 1039 fatal_exit("testbound: comm_base_exit was called."); 1040 } 1041 } 1042 1043 struct comm_signal* 1044 comm_signal_create(struct comm_base* base, 1045 void (*callback)(int, void*), void* cb_arg) 1046 { 1047 struct replay_runtime* runtime = (struct replay_runtime*)base; 1048 runtime->sig_cb = callback; 1049 runtime->sig_cb_arg = cb_arg; 1050 return calloc(1, sizeof(struct comm_signal)); 1051 } 1052 1053 int 1054 comm_signal_bind(struct comm_signal* ATTR_UNUSED(comsig), int 1055 ATTR_UNUSED(sig)) 1056 { 1057 return 1; 1058 } 1059 1060 void 1061 comm_signal_delete(struct comm_signal* comsig) 1062 { 1063 free(comsig); 1064 } 1065 1066 void 1067 comm_point_send_reply(struct comm_reply* repinfo) 1068 { 1069 struct replay_answer* ans = (struct replay_answer*)calloc(1, 1070 sizeof(struct replay_answer)); 1071 struct replay_runtime* runtime = (struct replay_runtime*)repinfo->c->ev; 1072 log_info("testbound: comm_point_send_reply fake"); 1073 /* dump it into the todo list */ 1074 log_assert(ans); 1075 memcpy(&ans->repinfo, repinfo, sizeof(struct comm_reply)); 1076 ans->next = NULL; 1077 if(runtime->answer_last) 1078 runtime->answer_last->next = ans; 1079 else runtime->answer_list = ans; 1080 runtime->answer_last = ans; 1081 1082 /* try to parse packet */ 1083 ans->pkt = memdup(sldns_buffer_begin(ans->repinfo.c->buffer), 1084 sldns_buffer_limit(ans->repinfo.c->buffer)); 1085 ans->pkt_len = sldns_buffer_limit(ans->repinfo.c->buffer); 1086 if(!ans->pkt) fatal_exit("out of memory"); 1087 log_pkt("reply pkt: ", ans->pkt, ans->pkt_len); 1088 } 1089 1090 void 1091 comm_point_drop_reply(struct comm_reply* repinfo) 1092 { 1093 log_info("comm_point_drop_reply fake"); 1094 if(repinfo->c) { 1095 sldns_buffer_free(repinfo->c->buffer); 1096 free(repinfo->c); 1097 } 1098 } 1099 1100 struct outside_network* 1101 outside_network_create(struct comm_base* base, size_t bufsize, 1102 size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs), 1103 int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4), 1104 int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp), 1105 int ATTR_UNUSED(dscp), 1106 struct infra_cache* infra, 1107 struct ub_randstate* ATTR_UNUSED(rnd), 1108 int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports), 1109 int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold), 1110 int ATTR_UNUSED(outgoing_tcp_mss), 1111 void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param), 1112 int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx), 1113 int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni), 1114 struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect), 1115 int ATTR_UNUSED(max_reuse_tcp_queries), int ATTR_UNUSED(tcp_reuse_timeout), 1116 int ATTR_UNUSED(tcp_auth_query_timeout)) 1117 { 1118 struct replay_runtime* runtime = (struct replay_runtime*)base; 1119 struct outside_network* outnet = calloc(1, 1120 sizeof(struct outside_network)); 1121 (void)unwanted_action; 1122 if(!outnet) 1123 return NULL; 1124 runtime->infra = infra; 1125 outnet->base = base; 1126 outnet->udp_buff = sldns_buffer_new(bufsize); 1127 if(!outnet->udp_buff) { 1128 free(outnet); 1129 return NULL; 1130 } 1131 return outnet; 1132 } 1133 1134 void 1135 outside_network_delete(struct outside_network* outnet) 1136 { 1137 if(!outnet) 1138 return; 1139 sldns_buffer_free(outnet->udp_buff); 1140 free(outnet); 1141 } 1142 1143 void 1144 outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet)) 1145 { 1146 } 1147 1148 struct pending* 1149 pending_udp_query(struct serviced_query* sq, sldns_buffer* packet, 1150 int timeout, comm_point_callback_type* callback, void* callback_arg) 1151 { 1152 struct replay_runtime* runtime = (struct replay_runtime*) 1153 sq->outnet->base; 1154 struct fake_pending* pend = (struct fake_pending*)calloc(1, 1155 sizeof(struct fake_pending)); 1156 log_assert(pend); 1157 pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet)); 1158 log_assert(pend->buffer); 1159 sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet), 1160 sldns_buffer_limit(packet)); 1161 sldns_buffer_flip(pend->buffer); 1162 memcpy(&pend->addr, &sq->addr, sq->addrlen); 1163 pend->addrlen = sq->addrlen; 1164 pend->callback = callback; 1165 pend->cb_arg = callback_arg; 1166 pend->timeout = timeout/1000; 1167 pend->transport = transport_udp; 1168 pend->pkt = NULL; 1169 pend->zone = NULL; 1170 pend->serviced = 0; 1171 pend->runtime = runtime; 1172 pend->pkt_len = sldns_buffer_limit(packet); 1173 pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len); 1174 if(!pend->pkt) fatal_exit("out of memory"); 1175 log_pkt("pending udp pkt: ", pend->pkt, pend->pkt_len); 1176 1177 /* see if it matches the current moment */ 1178 if(runtime->now && runtime->now->evt_type == repevt_back_query && 1179 (runtime->now->addrlen == 0 || sockaddr_cmp( 1180 &runtime->now->addr, runtime->now->addrlen, 1181 &pend->addr, pend->addrlen) == 0) && 1182 find_match(runtime->now->match, pend->pkt, pend->pkt_len, 1183 pend->transport)) { 1184 log_info("testbound: matched pending to event. " 1185 "advance time between events."); 1186 log_info("testbound: do STEP %d %s", runtime->now->time_step, 1187 repevt_string(runtime->now->evt_type)); 1188 advance_moment(runtime); 1189 /* still create the pending, because we need it to callback */ 1190 } 1191 log_info("testbound: created fake pending"); 1192 /* add to list */ 1193 pend->next = runtime->pending_list; 1194 runtime->pending_list = pend; 1195 return (struct pending*)pend; 1196 } 1197 1198 struct waiting_tcp* 1199 pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet, 1200 int timeout, comm_point_callback_type* callback, void* callback_arg) 1201 { 1202 struct replay_runtime* runtime = (struct replay_runtime*) 1203 sq->outnet->base; 1204 struct fake_pending* pend = (struct fake_pending*)calloc(1, 1205 sizeof(struct fake_pending)); 1206 log_assert(pend); 1207 pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet)); 1208 log_assert(pend->buffer); 1209 sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet), 1210 sldns_buffer_limit(packet)); 1211 sldns_buffer_flip(pend->buffer); 1212 memcpy(&pend->addr, &sq->addr, sq->addrlen); 1213 pend->addrlen = sq->addrlen; 1214 pend->callback = callback; 1215 pend->cb_arg = callback_arg; 1216 pend->timeout = timeout/1000; 1217 pend->transport = transport_tcp; 1218 pend->pkt = NULL; 1219 pend->zone = NULL; 1220 pend->runtime = runtime; 1221 pend->serviced = 0; 1222 pend->pkt_len = sldns_buffer_limit(packet); 1223 pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len); 1224 if(!pend->pkt) fatal_exit("out of memory"); 1225 log_pkt("pending tcp pkt: ", pend->pkt, pend->pkt_len); 1226 1227 /* see if it matches the current moment */ 1228 if(runtime->now && runtime->now->evt_type == repevt_back_query && 1229 (runtime->now->addrlen == 0 || sockaddr_cmp( 1230 &runtime->now->addr, runtime->now->addrlen, 1231 &pend->addr, pend->addrlen) == 0) && 1232 find_match(runtime->now->match, pend->pkt, pend->pkt_len, 1233 pend->transport)) { 1234 log_info("testbound: matched pending to event. " 1235 "advance time between events."); 1236 log_info("testbound: do STEP %d %s", runtime->now->time_step, 1237 repevt_string(runtime->now->evt_type)); 1238 advance_moment(runtime); 1239 /* still create the pending, because we need it to callback */ 1240 } 1241 log_info("testbound: created fake pending"); 1242 /* add to list */ 1243 pend->next = runtime->pending_list; 1244 runtime->pending_list = pend; 1245 return (struct waiting_tcp*)pend; 1246 } 1247 1248 struct serviced_query* outnet_serviced_query(struct outside_network* outnet, 1249 struct query_info* qinfo, uint16_t flags, int dnssec, 1250 int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), 1251 int ATTR_UNUSED(check_ratelimit), 1252 int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), 1253 char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr, 1254 socklen_t addrlen, uint8_t* zone, size_t zonelen, 1255 struct module_qstate* qstate, comm_point_callback_type* callback, 1256 void* callback_arg, sldns_buffer* ATTR_UNUSED(buff), 1257 struct module_env* env, int* ATTR_UNUSED(was_ratelimited)) 1258 { 1259 struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; 1260 struct fake_pending* pend = (struct fake_pending*)calloc(1, 1261 sizeof(struct fake_pending)); 1262 char z[256]; 1263 log_assert(pend); 1264 log_nametypeclass(VERB_OPS, "pending serviced query", 1265 qinfo->qname, qinfo->qtype, qinfo->qclass); 1266 dname_str(zone, z); 1267 verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s", 1268 z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"", 1269 (flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":""); 1270 1271 /* create packet with EDNS */ 1272 pend->buffer = sldns_buffer_new(512); 1273 log_assert(pend->buffer); 1274 sldns_buffer_write_u16(pend->buffer, 0); /* id */ 1275 sldns_buffer_write_u16(pend->buffer, flags); 1276 sldns_buffer_write_u16(pend->buffer, 1); /* qdcount */ 1277 sldns_buffer_write_u16(pend->buffer, 0); /* ancount */ 1278 sldns_buffer_write_u16(pend->buffer, 0); /* nscount */ 1279 sldns_buffer_write_u16(pend->buffer, 0); /* arcount */ 1280 sldns_buffer_write(pend->buffer, qinfo->qname, qinfo->qname_len); 1281 sldns_buffer_write_u16(pend->buffer, qinfo->qtype); 1282 sldns_buffer_write_u16(pend->buffer, qinfo->qclass); 1283 sldns_buffer_flip(pend->buffer); 1284 if(1) { 1285 struct edns_data edns; 1286 struct edns_string_addr* client_string_addr; 1287 struct edns_option* backed_up_opt_list = 1288 qstate->edns_opts_back_out; 1289 struct edns_option* per_upstream_opt_list = NULL; 1290 /* If we have an already populated EDNS option list make a copy 1291 * since we may now add upstream specific EDNS options. */ 1292 if(qstate->edns_opts_back_out) { 1293 per_upstream_opt_list = edns_opt_copy_region( 1294 qstate->edns_opts_back_out, qstate->region); 1295 if(!per_upstream_opt_list) { 1296 free(pend); 1297 fatal_exit("out of memory"); 1298 } 1299 qstate->edns_opts_back_out = per_upstream_opt_list; 1300 } 1301 if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, 1302 zone, zonelen, qstate, qstate->region)) { 1303 free(pend); 1304 return NULL; 1305 } 1306 /* Restore the option list; we can explicitly use the copied 1307 * one from now on. */ 1308 per_upstream_opt_list = qstate->edns_opts_back_out; 1309 qstate->edns_opts_back_out = backed_up_opt_list; 1310 if((client_string_addr = edns_string_addr_lookup( 1311 &env->edns_strings->client_strings, 1312 addr, addrlen))) { 1313 edns_opt_list_append(&per_upstream_opt_list, 1314 env->edns_strings->client_string_opcode, 1315 client_string_addr->string_len, 1316 client_string_addr->string, qstate->region); 1317 } 1318 /* add edns */ 1319 edns.edns_present = 1; 1320 edns.ext_rcode = 0; 1321 edns.edns_version = EDNS_ADVERTISED_VERSION; 1322 edns.udp_size = EDNS_ADVERTISED_SIZE; 1323 edns.bits = 0; 1324 if((dnssec & EDNS_DO)) 1325 edns.bits = EDNS_DO; 1326 edns.padding_block_size = 0; 1327 edns.cookie_present = 0; 1328 edns.cookie_valid = 0; 1329 edns.opt_list_in = NULL; 1330 edns.opt_list_out = per_upstream_opt_list; 1331 edns.opt_list_inplace_cb_out = NULL; 1332 attach_edns_record(pend->buffer, &edns); 1333 } 1334 memcpy(&pend->addr, addr, addrlen); 1335 pend->addrlen = addrlen; 1336 pend->zone = memdup(zone, zonelen); 1337 pend->zonelen = zonelen; 1338 pend->qtype = (int)qinfo->qtype; 1339 log_assert(pend->zone); 1340 pend->callback = callback; 1341 pend->cb_arg = callback_arg; 1342 pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000; 1343 pend->transport = transport_udp; /* pretend UDP */ 1344 pend->pkt = NULL; 1345 pend->runtime = runtime; 1346 pend->serviced = 1; 1347 pend->pkt_len = sldns_buffer_limit(pend->buffer); 1348 pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len); 1349 if(!pend->pkt) fatal_exit("out of memory"); 1350 /*log_pkt("pending serviced query: ", pend->pkt, pend->pkt_len);*/ 1351 1352 /* see if it matches the current moment */ 1353 if(runtime->now && runtime->now->evt_type == repevt_back_query && 1354 (runtime->now->addrlen == 0 || sockaddr_cmp( 1355 &runtime->now->addr, runtime->now->addrlen, 1356 &pend->addr, pend->addrlen) == 0) && 1357 find_match(runtime->now->match, pend->pkt, pend->pkt_len, 1358 pend->transport)) { 1359 log_info("testbound: matched pending to event. " 1360 "advance time between events."); 1361 log_info("testbound: do STEP %d %s", runtime->now->time_step, 1362 repevt_string(runtime->now->evt_type)); 1363 advance_moment(runtime); 1364 /* still create the pending, because we need it to callback */ 1365 } 1366 log_info("testbound: created fake pending"); 1367 /* add to list */ 1368 pend->next = runtime->pending_list; 1369 runtime->pending_list = pend; 1370 return (struct serviced_query*)pend; 1371 } 1372 1373 void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg) 1374 { 1375 struct fake_pending* pend = (struct fake_pending*)sq; 1376 struct replay_runtime* runtime = pend->runtime; 1377 /* delete from the list */ 1378 struct fake_pending* p = runtime->pending_list, *prev=NULL; 1379 while(p) { 1380 if(p == pend) { 1381 log_assert(p->cb_arg == cb_arg); 1382 (void)cb_arg; 1383 log_info("serviced pending delete"); 1384 if(prev) 1385 prev->next = p->next; 1386 else runtime->pending_list = p->next; 1387 sldns_buffer_free(p->buffer); 1388 free(p->pkt); 1389 free(p->zone); 1390 free(p); 1391 return; 1392 } 1393 prev = p; 1394 p = p->next; 1395 } 1396 log_info("double delete of pending serviced query"); 1397 } 1398 1399 int resolve_interface_names(char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs), 1400 struct config_strlist* ATTR_UNUSED(list), char*** ATTR_UNUSED(resif), 1401 int* ATTR_UNUSED(num_resif)) 1402 { 1403 return 1; 1404 } 1405 1406 struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg), 1407 char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs), 1408 int* ATTR_UNUSED(reuseport)) 1409 { 1410 return calloc(1, sizeof(struct listen_port)); 1411 } 1412 1413 void listening_ports_free(struct listen_port* list) 1414 { 1415 free(list); 1416 } 1417 1418 struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base), 1419 int ATTR_UNUSED(fd), size_t ATTR_UNUSED(bufsize), 1420 comm_point_callback_type* ATTR_UNUSED(callback), 1421 void* ATTR_UNUSED(callback_arg)) 1422 { 1423 struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1, 1424 sizeof(*fc)); 1425 if(!fc) return NULL; 1426 fc->typecode = FAKE_COMMPOINT_TYPECODE; 1427 return (struct comm_point*)fc; 1428 } 1429 1430 struct comm_point* comm_point_create_raw(struct comm_base* ATTR_UNUSED(base), 1431 int ATTR_UNUSED(fd), int ATTR_UNUSED(writing), 1432 comm_point_callback_type* ATTR_UNUSED(callback), 1433 void* ATTR_UNUSED(callback_arg)) 1434 { 1435 /* no pipe comm possible */ 1436 struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1, 1437 sizeof(*fc)); 1438 if(!fc) return NULL; 1439 fc->typecode = FAKE_COMMPOINT_TYPECODE; 1440 return (struct comm_point*)fc; 1441 } 1442 1443 void comm_point_start_listening(struct comm_point* ATTR_UNUSED(c), 1444 int ATTR_UNUSED(newfd), int ATTR_UNUSED(sec)) 1445 { 1446 /* no bg write pipe comm possible */ 1447 } 1448 1449 void comm_point_stop_listening(struct comm_point* ATTR_UNUSED(c)) 1450 { 1451 /* no bg write pipe comm possible */ 1452 } 1453 1454 /* only cmd com _local gets deleted */ 1455 void comm_point_delete(struct comm_point* c) 1456 { 1457 struct fake_commpoint* fc = (struct fake_commpoint*)c; 1458 if(c == NULL) return; 1459 log_assert(fc->typecode == FAKE_COMMPOINT_TYPECODE); 1460 if(fc->type_tcp_out) { 1461 /* remove tcp pending, so no more callbacks to it */ 1462 pending_list_delete(fc->runtime, fc->pending); 1463 } 1464 free(c); 1465 } 1466 1467 size_t listen_get_mem(struct listen_dnsport* ATTR_UNUSED(listen)) 1468 { 1469 return 0; 1470 } 1471 1472 size_t outnet_get_mem(struct outside_network* ATTR_UNUSED(outnet)) 1473 { 1474 return 0; 1475 } 1476 1477 size_t comm_point_get_mem(struct comm_point* ATTR_UNUSED(c)) 1478 { 1479 return 0; 1480 } 1481 1482 size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c)) 1483 { 1484 return 0; 1485 } 1486 1487 /* fake for fptr wlist */ 1488 int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c), 1489 void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 1490 struct comm_reply *ATTR_UNUSED(reply_info)) 1491 { 1492 log_assert(0); 1493 return 0; 1494 } 1495 1496 int outnet_tcp_cb(struct comm_point* ATTR_UNUSED(c), 1497 void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 1498 struct comm_reply *ATTR_UNUSED(reply_info)) 1499 { 1500 log_assert(0); 1501 return 0; 1502 } 1503 1504 void pending_udp_timer_cb(void *ATTR_UNUSED(arg)) 1505 { 1506 log_assert(0); 1507 } 1508 1509 void serviced_timer_cb(void *ATTR_UNUSED(arg)) 1510 { 1511 log_assert(0); 1512 } 1513 1514 void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg)) 1515 { 1516 log_assert(0); 1517 } 1518 1519 void outnet_tcptimer(void* ATTR_UNUSED(arg)) 1520 { 1521 log_assert(0); 1522 } 1523 1524 void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), 1525 void* ATTR_UNUSED(arg)) 1526 { 1527 log_assert(0); 1528 } 1529 1530 void comm_point_udp_ancil_callback(int ATTR_UNUSED(fd), 1531 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1532 { 1533 log_assert(0); 1534 } 1535 1536 void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd), 1537 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1538 { 1539 log_assert(0); 1540 } 1541 1542 void comm_point_tcp_handle_callback(int ATTR_UNUSED(fd), 1543 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1544 { 1545 log_assert(0); 1546 } 1547 1548 void comm_timer_callback(int ATTR_UNUSED(fd), 1549 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1550 { 1551 log_assert(0); 1552 } 1553 1554 void comm_signal_callback(int ATTR_UNUSED(fd), 1555 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1556 { 1557 log_assert(0); 1558 } 1559 1560 void comm_point_http_handle_callback(int ATTR_UNUSED(fd), 1561 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1562 { 1563 log_assert(0); 1564 } 1565 1566 void comm_point_local_handle_callback(int ATTR_UNUSED(fd), 1567 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1568 { 1569 log_assert(0); 1570 } 1571 1572 void comm_point_raw_handle_callback(int ATTR_UNUSED(fd), 1573 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1574 { 1575 log_assert(0); 1576 } 1577 1578 void comm_base_handle_slow_accept(int ATTR_UNUSED(fd), 1579 short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) 1580 { 1581 log_assert(0); 1582 } 1583 1584 int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c), 1585 void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 1586 struct comm_reply* ATTR_UNUSED(reply_info)) 1587 { 1588 log_assert(0); 1589 return 0; 1590 } 1591 1592 int serviced_tcp_callback(struct comm_point* ATTR_UNUSED(c), 1593 void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 1594 struct comm_reply* ATTR_UNUSED(reply_info)) 1595 { 1596 log_assert(0); 1597 return 0; 1598 } 1599 1600 int pending_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) 1601 { 1602 log_assert(0); 1603 return 0; 1604 } 1605 1606 int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) 1607 { 1608 log_assert(0); 1609 return 0; 1610 } 1611 1612 int reuse_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) 1613 { 1614 log_assert(0); 1615 return 0; 1616 } 1617 1618 int reuse_id_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) 1619 { 1620 log_assert(0); 1621 return 0; 1622 } 1623 1624 /* timers in testbound for autotrust. statistics tested in tdir. */ 1625 struct comm_timer* comm_timer_create(struct comm_base* base, 1626 void (*cb)(void*), void* cb_arg) 1627 { 1628 struct replay_runtime* runtime = (struct replay_runtime*)base; 1629 struct fake_timer* t = (struct fake_timer*)calloc(1, sizeof(*t)); 1630 if(!t) 1631 fatal_exit("out of memory in fake_event.c:comm_timer_create"); 1632 t->cb = cb; 1633 t->cb_arg = cb_arg; 1634 fptr_ok(fptr_whitelist_comm_timer(t->cb)); /* check in advance */ 1635 t->runtime = runtime; 1636 t->next = runtime->timer_list; 1637 runtime->timer_list = t; 1638 return (struct comm_timer*)t; 1639 } 1640 1641 void comm_timer_disable(struct comm_timer* timer) 1642 { 1643 struct fake_timer* t = (struct fake_timer*)timer; 1644 log_info("fake timer disabled"); 1645 t->enabled = 0; 1646 } 1647 1648 void comm_timer_set(struct comm_timer* timer, struct timeval* tv) 1649 { 1650 struct fake_timer* t = (struct fake_timer*)timer; 1651 t->enabled = 1; 1652 t->tv = *tv; 1653 log_info("fake timer set %d.%6.6d", 1654 (int)t->tv.tv_sec, (int)t->tv.tv_usec); 1655 timeval_add(&t->tv, &t->runtime->now_tv); 1656 } 1657 1658 int comm_timer_is_set(struct comm_timer* timer) 1659 { 1660 struct fake_timer* t = (struct fake_timer*)timer; 1661 return t->enabled; 1662 } 1663 1664 void comm_timer_delete(struct comm_timer* timer) 1665 { 1666 struct fake_timer* t = (struct fake_timer*)timer; 1667 struct fake_timer** pp, *p; 1668 if(!t) return; 1669 1670 /* remove from linked list */ 1671 pp = &t->runtime->timer_list; 1672 p = t->runtime->timer_list; 1673 while(p) { 1674 if(p == t) { 1675 /* snip from list */ 1676 *pp = p->next; 1677 break; 1678 } 1679 pp = &p->next; 1680 p = p->next; 1681 } 1682 1683 free(timer); 1684 } 1685 1686 void comm_base_set_slow_accept_handlers(struct comm_base* ATTR_UNUSED(b), 1687 void (*stop_acc)(void*), void (*start_acc)(void*), 1688 void* ATTR_UNUSED(arg)) 1689 { 1690 /* ignore this */ 1691 (void)stop_acc; 1692 (void)start_acc; 1693 } 1694 1695 struct ub_event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b)) 1696 { 1697 /* no pipe comm possible in testbound */ 1698 return NULL; 1699 } 1700 1701 void daemon_remote_exec(struct worker* ATTR_UNUSED(worker)) 1702 { 1703 } 1704 1705 void listen_start_accept(struct listen_dnsport* ATTR_UNUSED(listen)) 1706 { 1707 } 1708 1709 void listen_stop_accept(struct listen_dnsport* ATTR_UNUSED(listen)) 1710 { 1711 } 1712 1713 void daemon_remote_start_accept(struct daemon_remote* ATTR_UNUSED(rc)) 1714 { 1715 } 1716 1717 void daemon_remote_stop_accept(struct daemon_remote* ATTR_UNUSED(rc)) 1718 { 1719 } 1720 1721 int create_udp_sock(int ATTR_UNUSED(family), int ATTR_UNUSED(socktype), 1722 struct sockaddr* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), 1723 int ATTR_UNUSED(v6only), int* ATTR_UNUSED(inuse), 1724 int* ATTR_UNUSED(noproto), int ATTR_UNUSED(rcv), int ATTR_UNUSED(snd), 1725 int ATTR_UNUSED(listen), int* ATTR_UNUSED(reuseport), 1726 int ATTR_UNUSED(transparent), int ATTR_UNUSED(freebind), 1727 int ATTR_UNUSED(use_systemd), int ATTR_UNUSED(dscp)) 1728 { 1729 /* if you actually print to this, it'll be stdout during test */ 1730 return 1; 1731 } 1732 1733 struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base), 1734 int ATTR_UNUSED(fd), sldns_buffer* ATTR_UNUSED(buffer), 1735 int ATTR_UNUSED(pp2_enabled), 1736 comm_point_callback_type* ATTR_UNUSED(callback), 1737 void* ATTR_UNUSED(callback_arg), 1738 struct unbound_socket* ATTR_UNUSED(socket)) 1739 { 1740 log_assert(0); 1741 return NULL; 1742 } 1743 1744 struct comm_point* comm_point_create_tcp_out(struct comm_base* 1745 ATTR_UNUSED(base), size_t ATTR_UNUSED(bufsize), 1746 comm_point_callback_type* ATTR_UNUSED(callback), 1747 void* ATTR_UNUSED(callback_arg)) 1748 { 1749 log_assert(0); 1750 return NULL; 1751 } 1752 1753 struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet, 1754 comm_point_callback_type* cb, void* cb_arg, 1755 struct sockaddr_storage* ATTR_UNUSED(to_addr), 1756 socklen_t ATTR_UNUSED(to_addrlen)) 1757 { 1758 struct replay_runtime* runtime = (struct replay_runtime*) 1759 outnet->base; 1760 struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1, 1761 sizeof(*fc)); 1762 if(!fc) return NULL; 1763 fc->typecode = FAKE_COMMPOINT_TYPECODE; 1764 fc->type_udp_out = 1; 1765 fc->cb = cb; 1766 fc->cb_arg = cb_arg; 1767 fc->runtime = runtime; 1768 /* used by authzone transfers */ 1769 return (struct comm_point*)fc; 1770 } 1771 1772 struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet, 1773 comm_point_callback_type* cb, void* cb_arg, 1774 struct sockaddr_storage* to_addr, socklen_t to_addrlen, 1775 struct sldns_buffer* query, int timeout, int ATTR_UNUSED(ssl), 1776 char* ATTR_UNUSED(host)) 1777 { 1778 struct replay_runtime* runtime = (struct replay_runtime*) 1779 outnet->base; 1780 struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1, 1781 sizeof(*fc)); 1782 struct fake_pending* pend = (struct fake_pending*)calloc(1, 1783 sizeof(struct fake_pending)); 1784 if(!fc || !pend) { 1785 free(fc); 1786 free(pend); 1787 return NULL; 1788 } 1789 fc->typecode = FAKE_COMMPOINT_TYPECODE; 1790 fc->type_tcp_out = 1; 1791 fc->cb = cb; 1792 fc->cb_arg = cb_arg; 1793 fc->runtime = runtime; 1794 fc->pending = pend; 1795 1796 /* used by authzone transfers */ 1797 /* create pending item */ 1798 pend->buffer = sldns_buffer_new(sldns_buffer_limit(query)+10); 1799 if(!pend->buffer) { 1800 free(fc); 1801 free(pend); 1802 return NULL; 1803 } 1804 sldns_buffer_copy(pend->buffer, query); 1805 memcpy(&pend->addr, to_addr, to_addrlen); 1806 pend->addrlen = to_addrlen; 1807 pend->zone = NULL; 1808 pend->zonelen = 0; 1809 if(LDNS_QDCOUNT(sldns_buffer_begin(query)) > 0) { 1810 char buf[512]; 1811 char addrbuf[128]; 1812 (void)sldns_wire2str_rrquestion_buf(sldns_buffer_at(query, LDNS_HEADER_SIZE), sldns_buffer_limit(query)-LDNS_HEADER_SIZE, buf, sizeof(buf)); 1813 addr_to_str((struct sockaddr_storage*)to_addr, to_addrlen, 1814 addrbuf, sizeof(addrbuf)); 1815 if(verbosity >= VERB_ALGO) { 1816 strip_end_white(buf); 1817 log_info("tcp to %s: %s", addrbuf, buf); 1818 } 1819 log_assert(sldns_buffer_limit(query)-LDNS_HEADER_SIZE >= 2); 1820 pend->qtype = (int)sldns_buffer_read_u16_at(query, 1821 LDNS_HEADER_SIZE+ 1822 dname_valid(sldns_buffer_at(query, LDNS_HEADER_SIZE), 1823 sldns_buffer_limit(query)-LDNS_HEADER_SIZE)); 1824 } 1825 pend->callback = cb; 1826 pend->cb_arg = cb_arg; 1827 pend->timeout = timeout; 1828 pend->transport = transport_tcp; 1829 pend->pkt = NULL; 1830 pend->runtime = runtime; 1831 pend->serviced = 0; 1832 pend->pkt_len = sldns_buffer_limit(pend->buffer); 1833 pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len); 1834 if(!pend->pkt) fatal_exit("out of memory"); 1835 1836 log_info("testbound: created fake pending for tcp_out"); 1837 1838 /* add to list */ 1839 pend->next = runtime->pending_list; 1840 runtime->pending_list = pend; 1841 1842 return (struct comm_point*)fc; 1843 } 1844 1845 struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet, 1846 comm_point_callback_type* cb, void* cb_arg, 1847 struct sockaddr_storage* to_addr, socklen_t to_addrlen, int timeout, 1848 int ssl, char* host, char* path, struct config_file* cfg) 1849 { 1850 struct replay_runtime* runtime = (struct replay_runtime*) 1851 outnet->base; 1852 struct fake_commpoint* fc = (struct fake_commpoint*)calloc(1, 1853 sizeof(*fc)); 1854 if(!fc) { 1855 return NULL; 1856 } 1857 fc->typecode = FAKE_COMMPOINT_TYPECODE; 1858 fc->type_http_out = 1; 1859 fc->cb = cb; 1860 fc->cb_arg = cb_arg; 1861 fc->runtime = runtime; 1862 1863 (void)to_addr; 1864 (void)to_addrlen; 1865 (void)timeout; 1866 1867 (void)ssl; 1868 (void)host; 1869 (void)path; 1870 (void)cfg; 1871 1872 /* handle http comm point and return contents from test script */ 1873 return (struct comm_point*)fc; 1874 } 1875 1876 int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, 1877 struct sockaddr* addr, socklen_t addrlen, int ATTR_UNUSED(is_connected)) 1878 { 1879 struct fake_commpoint* fc = (struct fake_commpoint*)c; 1880 struct replay_runtime* runtime = fc->runtime; 1881 struct fake_pending* pend = (struct fake_pending*)calloc(1, 1882 sizeof(struct fake_pending)); 1883 if(!pend) { 1884 log_err("malloc failure"); 1885 return 0; 1886 } 1887 fc->pending = pend; 1888 /* used by authzone transfers */ 1889 /* create pending item */ 1890 pend->buffer = sldns_buffer_new(sldns_buffer_limit(packet) + 10); 1891 if(!pend->buffer) { 1892 free(pend); 1893 return 0; 1894 } 1895 sldns_buffer_copy(pend->buffer, packet); 1896 memcpy(&pend->addr, addr, addrlen); 1897 pend->addrlen = addrlen; 1898 pend->zone = NULL; 1899 pend->zonelen = 0; 1900 if(LDNS_QDCOUNT(sldns_buffer_begin(packet)) > 0) { 1901 char buf[512]; 1902 char addrbuf[128]; 1903 (void)sldns_wire2str_rrquestion_buf(sldns_buffer_at(packet, LDNS_HEADER_SIZE), sldns_buffer_limit(packet)-LDNS_HEADER_SIZE, buf, sizeof(buf)); 1904 addr_to_str((struct sockaddr_storage*)addr, addrlen, 1905 addrbuf, sizeof(addrbuf)); 1906 if(verbosity >= VERB_ALGO) { 1907 strip_end_white(buf); 1908 log_info("udp to %s: %s", addrbuf, buf); 1909 } 1910 log_assert(sldns_buffer_limit(packet)-LDNS_HEADER_SIZE >= 2); 1911 pend->qtype = (int)sldns_buffer_read_u16_at(packet, 1912 LDNS_HEADER_SIZE+ 1913 dname_valid(sldns_buffer_at(packet, LDNS_HEADER_SIZE), 1914 sldns_buffer_limit(packet)-LDNS_HEADER_SIZE)); 1915 } 1916 pend->callback = fc->cb; 1917 pend->cb_arg = fc->cb_arg; 1918 pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000; 1919 pend->transport = transport_udp; 1920 pend->pkt = NULL; 1921 pend->runtime = runtime; 1922 pend->serviced = 0; 1923 pend->pkt_len = sldns_buffer_limit(pend->buffer); 1924 pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len); 1925 if(!pend->pkt) fatal_exit("out of memory"); 1926 1927 log_info("testbound: created fake pending for send_udp_msg"); 1928 1929 /* add to list */ 1930 pend->next = runtime->pending_list; 1931 runtime->pending_list = pend; 1932 1933 return 1; 1934 } 1935 1936 int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr), 1937 socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), int ATTR_UNUSED(dscp)) 1938 { 1939 log_assert(0); 1940 return -1; 1941 } 1942 1943 int outnet_tcp_connect(int ATTR_UNUSED(s), struct sockaddr_storage* ATTR_UNUSED(addr), 1944 socklen_t ATTR_UNUSED(addrlen)) 1945 { 1946 log_assert(0); 1947 return 0; 1948 } 1949 1950 int tcp_req_info_add_meshstate(struct tcp_req_info* ATTR_UNUSED(req), 1951 struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m)) 1952 { 1953 log_assert(0); 1954 return 0; 1955 } 1956 1957 void 1958 tcp_req_info_remove_mesh_state(struct tcp_req_info* ATTR_UNUSED(req), 1959 struct mesh_state* ATTR_UNUSED(m)) 1960 { 1961 log_assert(0); 1962 } 1963 1964 size_t 1965 tcp_req_info_get_stream_buffer_size(void) 1966 { 1967 return 0; 1968 } 1969 1970 size_t 1971 http2_get_query_buffer_size(void) 1972 { 1973 return 0; 1974 } 1975 1976 size_t 1977 http2_get_response_buffer_size(void) 1978 { 1979 return 0; 1980 } 1981 1982 void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream), 1983 struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m)) 1984 { 1985 } 1986 1987 void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream)) 1988 { 1989 } 1990 1991 /*********** End of Dummy routines ***********/ 1992