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