1 /* 2 * unbound.c - unbound validating resolver public API implementation 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 * 39 * This file contains functions to resolve DNS queries and 40 * validate the answers. Synchonously and asynchronously. 41 * 42 */ 43 44 /* include the public api first, it should be able to stand alone */ 45 #include "libunbound/unbound.h" 46 #include "libunbound/unbound-event.h" 47 #include "config.h" 48 #include <ctype.h> 49 #include "libunbound/context.h" 50 #include "libunbound/libworker.h" 51 #include "util/locks.h" 52 #include "util/config_file.h" 53 #include "util/alloc.h" 54 #include "util/module.h" 55 #include "util/regional.h" 56 #include "util/log.h" 57 #include "util/random.h" 58 #include "util/net_help.h" 59 #include "util/tube.h" 60 #include "services/modstack.h" 61 #include "services/localzone.h" 62 #include "services/cache/infra.h" 63 #include "services/cache/rrset.h" 64 #include "sldns/sbuffer.h" 65 #ifdef HAVE_PTHREAD 66 #include <signal.h> 67 #endif 68 #ifdef HAVE_SYS_WAIT_H 69 #include <sys/wait.h> 70 #endif 71 #ifdef HAVE_TIME_H 72 #include <time.h> 73 #endif 74 75 #if defined(UB_ON_WINDOWS) && defined (HAVE_WINDOWS_H) 76 #include <windows.h> 77 #include <iphlpapi.h> 78 #endif /* UB_ON_WINDOWS */ 79 80 /** create context functionality, but no pipes */ 81 static struct ub_ctx* ub_ctx_create_nopipe(void) 82 { 83 struct ub_ctx* ctx; 84 unsigned int seed; 85 #ifdef USE_WINSOCK 86 int r; 87 WSADATA wsa_data; 88 #endif 89 90 log_init(NULL, 0, NULL); /* logs to stderr */ 91 log_ident_set("libunbound"); 92 #ifdef USE_WINSOCK 93 if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) { 94 log_err("could not init winsock. WSAStartup: %s", 95 wsa_strerror(r)); 96 return NULL; 97 } 98 #endif 99 verbosity = 0; /* errors only */ 100 checklock_start(); 101 ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx)); 102 if(!ctx) { 103 errno = ENOMEM; 104 return NULL; 105 } 106 alloc_init(&ctx->superalloc, NULL, 0); 107 seed = (unsigned int)time(NULL) ^ (unsigned int)getpid(); 108 if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) { 109 seed = 0; 110 ub_randfree(ctx->seed_rnd); 111 free(ctx); 112 errno = ENOMEM; 113 return NULL; 114 } 115 seed = 0; 116 lock_basic_init(&ctx->qqpipe_lock); 117 lock_basic_init(&ctx->rrpipe_lock); 118 lock_basic_init(&ctx->cfglock); 119 ctx->env = (struct module_env*)calloc(1, sizeof(*ctx->env)); 120 if(!ctx->env) { 121 ub_randfree(ctx->seed_rnd); 122 free(ctx); 123 errno = ENOMEM; 124 return NULL; 125 } 126 ctx->env->cfg = config_create_forlib(); 127 if(!ctx->env->cfg) { 128 free(ctx->env); 129 ub_randfree(ctx->seed_rnd); 130 free(ctx); 131 errno = ENOMEM; 132 return NULL; 133 } 134 ctx->env->alloc = &ctx->superalloc; 135 ctx->env->worker = NULL; 136 ctx->env->need_to_validate = 0; 137 modstack_init(&ctx->mods); 138 rbtree_init(&ctx->queries, &context_query_cmp); 139 return ctx; 140 } 141 142 struct ub_ctx* 143 ub_ctx_create(void) 144 { 145 struct ub_ctx* ctx = ub_ctx_create_nopipe(); 146 if(!ctx) 147 return NULL; 148 if((ctx->qq_pipe = tube_create()) == NULL) { 149 int e = errno; 150 ub_randfree(ctx->seed_rnd); 151 config_delete(ctx->env->cfg); 152 modstack_desetup(&ctx->mods, ctx->env); 153 free(ctx->env); 154 free(ctx); 155 errno = e; 156 return NULL; 157 } 158 if((ctx->rr_pipe = tube_create()) == NULL) { 159 int e = errno; 160 tube_delete(ctx->qq_pipe); 161 ub_randfree(ctx->seed_rnd); 162 config_delete(ctx->env->cfg); 163 modstack_desetup(&ctx->mods, ctx->env); 164 free(ctx->env); 165 free(ctx); 166 errno = e; 167 return NULL; 168 } 169 return ctx; 170 } 171 172 struct ub_ctx* 173 ub_ctx_create_event(struct event_base* eb) 174 { 175 struct ub_ctx* ctx = ub_ctx_create_nopipe(); 176 if(!ctx) 177 return NULL; 178 /* no pipes, but we have the locks to make sure everything works */ 179 ctx->created_bg = 0; 180 ctx->dothread = 1; /* the processing is in the same process, 181 makes ub_cancel and ub_ctx_delete do the right thing */ 182 ctx->event_base = eb; 183 return ctx; 184 } 185 186 /** delete q */ 187 static void 188 delq(rbnode_t* n, void* ATTR_UNUSED(arg)) 189 { 190 struct ctx_query* q = (struct ctx_query*)n; 191 context_query_delete(q); 192 } 193 194 /** stop the bg thread */ 195 static void ub_stop_bg(struct ub_ctx* ctx) 196 { 197 /* stop the bg thread */ 198 lock_basic_lock(&ctx->cfglock); 199 if(ctx->created_bg) { 200 uint8_t* msg; 201 uint32_t len; 202 uint32_t cmd = UB_LIBCMD_QUIT; 203 lock_basic_unlock(&ctx->cfglock); 204 lock_basic_lock(&ctx->qqpipe_lock); 205 (void)tube_write_msg(ctx->qq_pipe, (uint8_t*)&cmd, 206 (uint32_t)sizeof(cmd), 0); 207 lock_basic_unlock(&ctx->qqpipe_lock); 208 lock_basic_lock(&ctx->rrpipe_lock); 209 while(tube_read_msg(ctx->rr_pipe, &msg, &len, 0)) { 210 /* discard all results except a quit confirm */ 211 if(context_serial_getcmd(msg, len) == UB_LIBCMD_QUIT) { 212 free(msg); 213 break; 214 } 215 free(msg); 216 } 217 lock_basic_unlock(&ctx->rrpipe_lock); 218 219 /* if bg worker is a thread, wait for it to exit, so that all 220 * resources are really gone. */ 221 lock_basic_lock(&ctx->cfglock); 222 if(ctx->dothread) { 223 lock_basic_unlock(&ctx->cfglock); 224 ub_thread_join(ctx->bg_tid); 225 } else { 226 lock_basic_unlock(&ctx->cfglock); 227 #ifndef UB_ON_WINDOWS 228 if(waitpid(ctx->bg_pid, NULL, 0) == -1) { 229 if(verbosity > 2) 230 log_err("waitpid: %s", strerror(errno)); 231 } 232 #endif 233 } 234 } 235 else { 236 lock_basic_unlock(&ctx->cfglock); 237 } 238 } 239 240 void 241 ub_ctx_delete(struct ub_ctx* ctx) 242 { 243 struct alloc_cache* a, *na; 244 int do_stop = 1; 245 if(!ctx) return; 246 247 /* see if bg thread is created and if threads have been killed */ 248 /* no locks, because those may be held by terminated threads */ 249 /* for processes the read pipe is closed and we see that on read */ 250 #ifdef HAVE_PTHREAD 251 if(ctx->created_bg && ctx->dothread) { 252 if(pthread_kill(ctx->bg_tid, 0) == ESRCH) { 253 /* thread has been killed */ 254 do_stop = 0; 255 } 256 } 257 #endif /* HAVE_PTHREAD */ 258 if(do_stop) 259 ub_stop_bg(ctx); 260 libworker_delete_event(ctx->event_worker); 261 262 modstack_desetup(&ctx->mods, ctx->env); 263 a = ctx->alloc_list; 264 while(a) { 265 na = a->super; 266 a->super = &ctx->superalloc; 267 alloc_clear(a); 268 free(a); 269 a = na; 270 } 271 local_zones_delete(ctx->local_zones); 272 lock_basic_destroy(&ctx->qqpipe_lock); 273 lock_basic_destroy(&ctx->rrpipe_lock); 274 lock_basic_destroy(&ctx->cfglock); 275 tube_delete(ctx->qq_pipe); 276 tube_delete(ctx->rr_pipe); 277 if(ctx->env) { 278 slabhash_delete(ctx->env->msg_cache); 279 rrset_cache_delete(ctx->env->rrset_cache); 280 infra_delete(ctx->env->infra_cache); 281 config_delete(ctx->env->cfg); 282 free(ctx->env); 283 } 284 ub_randfree(ctx->seed_rnd); 285 alloc_clear(&ctx->superalloc); 286 traverse_postorder(&ctx->queries, delq, NULL); 287 free(ctx); 288 #ifdef USE_WINSOCK 289 WSACleanup(); 290 #endif 291 } 292 293 int 294 ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val) 295 { 296 lock_basic_lock(&ctx->cfglock); 297 if(ctx->finalized) { 298 lock_basic_unlock(&ctx->cfglock); 299 return UB_AFTERFINAL; 300 } 301 if(!config_set_option(ctx->env->cfg, opt, val)) { 302 lock_basic_unlock(&ctx->cfglock); 303 return UB_SYNTAX; 304 } 305 lock_basic_unlock(&ctx->cfglock); 306 return UB_NOERROR; 307 } 308 309 int 310 ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str) 311 { 312 int r; 313 lock_basic_lock(&ctx->cfglock); 314 r = config_get_option_collate(ctx->env->cfg, opt, str); 315 lock_basic_unlock(&ctx->cfglock); 316 if(r == 0) r = UB_NOERROR; 317 else if(r == 1) r = UB_SYNTAX; 318 else if(r == 2) r = UB_NOMEM; 319 return r; 320 } 321 322 int 323 ub_ctx_config(struct ub_ctx* ctx, const char* fname) 324 { 325 lock_basic_lock(&ctx->cfglock); 326 if(ctx->finalized) { 327 lock_basic_unlock(&ctx->cfglock); 328 return UB_AFTERFINAL; 329 } 330 if(!config_read(ctx->env->cfg, fname, NULL)) { 331 lock_basic_unlock(&ctx->cfglock); 332 return UB_SYNTAX; 333 } 334 lock_basic_unlock(&ctx->cfglock); 335 return UB_NOERROR; 336 } 337 338 int 339 ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta) 340 { 341 char* dup = strdup(ta); 342 if(!dup) return UB_NOMEM; 343 lock_basic_lock(&ctx->cfglock); 344 if(ctx->finalized) { 345 lock_basic_unlock(&ctx->cfglock); 346 free(dup); 347 return UB_AFTERFINAL; 348 } 349 if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) { 350 lock_basic_unlock(&ctx->cfglock); 351 free(dup); 352 return UB_NOMEM; 353 } 354 lock_basic_unlock(&ctx->cfglock); 355 return UB_NOERROR; 356 } 357 358 int 359 ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname) 360 { 361 char* dup = strdup(fname); 362 if(!dup) return UB_NOMEM; 363 lock_basic_lock(&ctx->cfglock); 364 if(ctx->finalized) { 365 lock_basic_unlock(&ctx->cfglock); 366 free(dup); 367 return UB_AFTERFINAL; 368 } 369 if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_file_list, dup)) { 370 lock_basic_unlock(&ctx->cfglock); 371 free(dup); 372 return UB_NOMEM; 373 } 374 lock_basic_unlock(&ctx->cfglock); 375 return UB_NOERROR; 376 } 377 378 int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname) 379 { 380 char* dup = strdup(fname); 381 if(!dup) return UB_NOMEM; 382 lock_basic_lock(&ctx->cfglock); 383 if(ctx->finalized) { 384 lock_basic_unlock(&ctx->cfglock); 385 free(dup); 386 return UB_AFTERFINAL; 387 } 388 if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list, 389 dup)) { 390 lock_basic_unlock(&ctx->cfglock); 391 free(dup); 392 return UB_NOMEM; 393 } 394 lock_basic_unlock(&ctx->cfglock); 395 return UB_NOERROR; 396 } 397 398 int 399 ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname) 400 { 401 char* dup = strdup(fname); 402 if(!dup) return UB_NOMEM; 403 lock_basic_lock(&ctx->cfglock); 404 if(ctx->finalized) { 405 lock_basic_unlock(&ctx->cfglock); 406 free(dup); 407 return UB_AFTERFINAL; 408 } 409 if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) { 410 lock_basic_unlock(&ctx->cfglock); 411 free(dup); 412 return UB_NOMEM; 413 } 414 lock_basic_unlock(&ctx->cfglock); 415 return UB_NOERROR; 416 } 417 418 int 419 ub_ctx_debuglevel(struct ub_ctx* ctx, int d) 420 { 421 lock_basic_lock(&ctx->cfglock); 422 verbosity = d; 423 ctx->env->cfg->verbosity = d; 424 lock_basic_unlock(&ctx->cfglock); 425 return UB_NOERROR; 426 } 427 428 int ub_ctx_debugout(struct ub_ctx* ctx, void* out) 429 { 430 lock_basic_lock(&ctx->cfglock); 431 log_file((FILE*)out); 432 ctx->logfile_override = 1; 433 ctx->log_out = out; 434 lock_basic_unlock(&ctx->cfglock); 435 return UB_NOERROR; 436 } 437 438 int 439 ub_ctx_async(struct ub_ctx* ctx, int dothread) 440 { 441 #ifdef THREADS_DISABLED 442 if(dothread) /* cannot do threading */ 443 return UB_NOERROR; 444 #endif 445 lock_basic_lock(&ctx->cfglock); 446 if(ctx->finalized) { 447 lock_basic_unlock(&ctx->cfglock); 448 return UB_AFTERFINAL; 449 } 450 ctx->dothread = dothread; 451 lock_basic_unlock(&ctx->cfglock); 452 return UB_NOERROR; 453 } 454 455 int 456 ub_poll(struct ub_ctx* ctx) 457 { 458 /* no need to hold lock while testing for readability. */ 459 return tube_poll(ctx->rr_pipe); 460 } 461 462 int 463 ub_fd(struct ub_ctx* ctx) 464 { 465 return tube_read_fd(ctx->rr_pipe); 466 } 467 468 /** process answer from bg worker */ 469 static int 470 process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len, 471 ub_callback_t* cb, void** cbarg, int* err, 472 struct ub_result** res) 473 { 474 struct ctx_query* q; 475 if(context_serial_getcmd(msg, len) != UB_LIBCMD_ANSWER) { 476 log_err("error: bad data from bg worker %d", 477 (int)context_serial_getcmd(msg, len)); 478 return 0; 479 } 480 481 lock_basic_lock(&ctx->cfglock); 482 q = context_deserialize_answer(ctx, msg, len, err); 483 if(!q) { 484 lock_basic_unlock(&ctx->cfglock); 485 /* probably simply the lookup that failed, i.e. 486 * response returned before cancel was sent out, so noerror */ 487 return 1; 488 } 489 log_assert(q->async); 490 491 /* grab cb while locked */ 492 if(q->cancelled) { 493 *cb = NULL; 494 *cbarg = NULL; 495 } else { 496 *cb = q->cb; 497 *cbarg = q->cb_arg; 498 } 499 if(*err) { 500 *res = NULL; 501 ub_resolve_free(q->res); 502 } else { 503 /* parse the message, extract rcode, fill result */ 504 sldns_buffer* buf = sldns_buffer_new(q->msg_len); 505 struct regional* region = regional_create(); 506 *res = q->res; 507 (*res)->rcode = LDNS_RCODE_SERVFAIL; 508 if(region && buf) { 509 sldns_buffer_clear(buf); 510 sldns_buffer_write(buf, q->msg, q->msg_len); 511 sldns_buffer_flip(buf); 512 libworker_enter_result(*res, buf, region, 513 q->msg_security); 514 } 515 (*res)->answer_packet = q->msg; 516 (*res)->answer_len = (int)q->msg_len; 517 q->msg = NULL; 518 sldns_buffer_free(buf); 519 regional_destroy(region); 520 } 521 q->res = NULL; 522 /* delete the q from list */ 523 (void)rbtree_delete(&ctx->queries, q->node.key); 524 ctx->num_async--; 525 context_query_delete(q); 526 lock_basic_unlock(&ctx->cfglock); 527 528 if(*cb) return 2; 529 ub_resolve_free(*res); 530 return 1; 531 } 532 533 /** process answer from bg worker */ 534 static int 535 process_answer(struct ub_ctx* ctx, uint8_t* msg, uint32_t len) 536 { 537 int err; 538 ub_callback_t cb; 539 void* cbarg; 540 struct ub_result* res; 541 int r; 542 543 r = process_answer_detail(ctx, msg, len, &cb, &cbarg, &err, &res); 544 545 /* no locks held while calling callback, so that library is 546 * re-entrant. */ 547 if(r == 2) 548 (*cb)(cbarg, err, res); 549 550 return r; 551 } 552 553 int 554 ub_process(struct ub_ctx* ctx) 555 { 556 int r; 557 uint8_t* msg; 558 uint32_t len; 559 while(1) { 560 msg = NULL; 561 lock_basic_lock(&ctx->rrpipe_lock); 562 r = tube_read_msg(ctx->rr_pipe, &msg, &len, 1); 563 lock_basic_unlock(&ctx->rrpipe_lock); 564 if(r == 0) 565 return UB_PIPE; 566 else if(r == -1) 567 break; 568 if(!process_answer(ctx, msg, len)) { 569 free(msg); 570 return UB_PIPE; 571 } 572 free(msg); 573 } 574 return UB_NOERROR; 575 } 576 577 int 578 ub_wait(struct ub_ctx* ctx) 579 { 580 int err; 581 ub_callback_t cb; 582 void* cbarg; 583 struct ub_result* res; 584 int r; 585 uint8_t* msg; 586 uint32_t len; 587 /* this is basically the same loop as _process(), but with changes. 588 * holds the rrpipe lock and waits with tube_wait */ 589 while(1) { 590 lock_basic_lock(&ctx->rrpipe_lock); 591 lock_basic_lock(&ctx->cfglock); 592 if(ctx->num_async == 0) { 593 lock_basic_unlock(&ctx->cfglock); 594 lock_basic_unlock(&ctx->rrpipe_lock); 595 break; 596 } 597 lock_basic_unlock(&ctx->cfglock); 598 599 /* keep rrpipe locked, while 600 * o waiting for pipe readable 601 * o parsing message 602 * o possibly decrementing num_async 603 * do callback without lock 604 */ 605 r = tube_wait(ctx->rr_pipe); 606 if(r) { 607 r = tube_read_msg(ctx->rr_pipe, &msg, &len, 1); 608 if(r == 0) { 609 lock_basic_unlock(&ctx->rrpipe_lock); 610 return UB_PIPE; 611 } 612 if(r == -1) { 613 lock_basic_unlock(&ctx->rrpipe_lock); 614 continue; 615 } 616 r = process_answer_detail(ctx, msg, len, 617 &cb, &cbarg, &err, &res); 618 lock_basic_unlock(&ctx->rrpipe_lock); 619 free(msg); 620 if(r == 0) 621 return UB_PIPE; 622 if(r == 2) 623 (*cb)(cbarg, err, res); 624 } else { 625 lock_basic_unlock(&ctx->rrpipe_lock); 626 } 627 } 628 return UB_NOERROR; 629 } 630 631 int 632 ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, 633 int rrclass, struct ub_result** result) 634 { 635 struct ctx_query* q; 636 int r; 637 *result = NULL; 638 639 lock_basic_lock(&ctx->cfglock); 640 if(!ctx->finalized) { 641 r = context_finalize(ctx); 642 if(r) { 643 lock_basic_unlock(&ctx->cfglock); 644 return r; 645 } 646 } 647 /* create new ctx_query and attempt to add to the list */ 648 lock_basic_unlock(&ctx->cfglock); 649 q = context_new(ctx, name, rrtype, rrclass, NULL, NULL); 650 if(!q) 651 return UB_NOMEM; 652 /* become a resolver thread for a bit */ 653 654 r = libworker_fg(ctx, q); 655 if(r) { 656 lock_basic_lock(&ctx->cfglock); 657 (void)rbtree_delete(&ctx->queries, q->node.key); 658 context_query_delete(q); 659 lock_basic_unlock(&ctx->cfglock); 660 return r; 661 } 662 q->res->answer_packet = q->msg; 663 q->res->answer_len = (int)q->msg_len; 664 q->msg = NULL; 665 *result = q->res; 666 q->res = NULL; 667 668 lock_basic_lock(&ctx->cfglock); 669 (void)rbtree_delete(&ctx->queries, q->node.key); 670 context_query_delete(q); 671 lock_basic_unlock(&ctx->cfglock); 672 return UB_NOERROR; 673 } 674 675 int 676 ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, 677 int rrclass, void* mydata, ub_event_callback_t callback, int* async_id) 678 { 679 struct ctx_query* q; 680 int r; 681 682 if(async_id) 683 *async_id = 0; 684 lock_basic_lock(&ctx->cfglock); 685 if(!ctx->finalized) { 686 int r = context_finalize(ctx); 687 if(r) { 688 lock_basic_unlock(&ctx->cfglock); 689 return r; 690 } 691 } 692 lock_basic_unlock(&ctx->cfglock); 693 if(!ctx->event_worker) { 694 ctx->event_worker = libworker_create_event(ctx, 695 ctx->event_base); 696 if(!ctx->event_worker) { 697 return UB_INITFAIL; 698 } 699 } 700 701 /* create new ctx_query and attempt to add to the list */ 702 q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback, 703 mydata); 704 if(!q) 705 return UB_NOMEM; 706 707 /* attach to mesh */ 708 if((r=libworker_attach_mesh(ctx, q, async_id)) != 0) 709 return r; 710 return UB_NOERROR; 711 } 712 713 714 int 715 ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype, 716 int rrclass, void* mydata, ub_callback_t callback, int* async_id) 717 { 718 struct ctx_query* q; 719 uint8_t* msg = NULL; 720 uint32_t len = 0; 721 722 if(async_id) 723 *async_id = 0; 724 lock_basic_lock(&ctx->cfglock); 725 if(!ctx->finalized) { 726 int r = context_finalize(ctx); 727 if(r) { 728 lock_basic_unlock(&ctx->cfglock); 729 return r; 730 } 731 } 732 if(!ctx->created_bg) { 733 int r; 734 ctx->created_bg = 1; 735 lock_basic_unlock(&ctx->cfglock); 736 r = libworker_bg(ctx); 737 if(r) { 738 lock_basic_lock(&ctx->cfglock); 739 ctx->created_bg = 0; 740 lock_basic_unlock(&ctx->cfglock); 741 return r; 742 } 743 } else { 744 lock_basic_unlock(&ctx->cfglock); 745 } 746 747 /* create new ctx_query and attempt to add to the list */ 748 q = context_new(ctx, name, rrtype, rrclass, callback, mydata); 749 if(!q) 750 return UB_NOMEM; 751 752 /* write over pipe to background worker */ 753 lock_basic_lock(&ctx->cfglock); 754 msg = context_serialize_new_query(q, &len); 755 if(!msg) { 756 (void)rbtree_delete(&ctx->queries, q->node.key); 757 ctx->num_async--; 758 context_query_delete(q); 759 lock_basic_unlock(&ctx->cfglock); 760 return UB_NOMEM; 761 } 762 if(async_id) 763 *async_id = q->querynum; 764 lock_basic_unlock(&ctx->cfglock); 765 766 lock_basic_lock(&ctx->qqpipe_lock); 767 if(!tube_write_msg(ctx->qq_pipe, msg, len, 0)) { 768 lock_basic_unlock(&ctx->qqpipe_lock); 769 free(msg); 770 return UB_PIPE; 771 } 772 lock_basic_unlock(&ctx->qqpipe_lock); 773 free(msg); 774 return UB_NOERROR; 775 } 776 777 int 778 ub_cancel(struct ub_ctx* ctx, int async_id) 779 { 780 struct ctx_query* q; 781 uint8_t* msg = NULL; 782 uint32_t len = 0; 783 lock_basic_lock(&ctx->cfglock); 784 q = (struct ctx_query*)rbtree_search(&ctx->queries, &async_id); 785 if(!q || !q->async) { 786 /* it is not there, so nothing to do */ 787 lock_basic_unlock(&ctx->cfglock); 788 return UB_NOID; 789 } 790 log_assert(q->async); 791 q->cancelled = 1; 792 793 /* delete it */ 794 if(!ctx->dothread) { /* if forked */ 795 (void)rbtree_delete(&ctx->queries, q->node.key); 796 ctx->num_async--; 797 msg = context_serialize_cancel(q, &len); 798 context_query_delete(q); 799 lock_basic_unlock(&ctx->cfglock); 800 if(!msg) { 801 return UB_NOMEM; 802 } 803 /* send cancel to background worker */ 804 lock_basic_lock(&ctx->qqpipe_lock); 805 if(!tube_write_msg(ctx->qq_pipe, msg, len, 0)) { 806 lock_basic_unlock(&ctx->qqpipe_lock); 807 free(msg); 808 return UB_PIPE; 809 } 810 lock_basic_unlock(&ctx->qqpipe_lock); 811 free(msg); 812 } else { 813 lock_basic_unlock(&ctx->cfglock); 814 } 815 return UB_NOERROR; 816 } 817 818 void 819 ub_resolve_free(struct ub_result* result) 820 { 821 char** p; 822 if(!result) return; 823 free(result->qname); 824 if(result->canonname != result->qname) 825 free(result->canonname); 826 if(result->data) 827 for(p = result->data; *p; p++) 828 free(*p); 829 free(result->data); 830 free(result->len); 831 free(result->answer_packet); 832 free(result->why_bogus); 833 free(result); 834 } 835 836 const char* 837 ub_strerror(int err) 838 { 839 switch(err) { 840 case UB_NOERROR: return "no error"; 841 case UB_SOCKET: return "socket io error"; 842 case UB_NOMEM: return "out of memory"; 843 case UB_SYNTAX: return "syntax error"; 844 case UB_SERVFAIL: return "server failure"; 845 case UB_FORKFAIL: return "could not fork"; 846 case UB_INITFAIL: return "initialization failure"; 847 case UB_AFTERFINAL: return "setting change after finalize"; 848 case UB_PIPE: return "error in pipe communication with async"; 849 case UB_READFILE: return "error reading file"; 850 case UB_NOID: return "error async_id does not exist"; 851 default: return "unknown error"; 852 } 853 } 854 855 int 856 ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) 857 { 858 struct sockaddr_storage storage; 859 socklen_t stlen; 860 struct config_stub* s; 861 char* dupl; 862 lock_basic_lock(&ctx->cfglock); 863 if(ctx->finalized) { 864 lock_basic_unlock(&ctx->cfglock); 865 errno=EINVAL; 866 return UB_AFTERFINAL; 867 } 868 if(!addr) { 869 /* disable fwd mode - the root stub should be first. */ 870 if(ctx->env->cfg->forwards && 871 strcmp(ctx->env->cfg->forwards->name, ".") == 0) { 872 s = ctx->env->cfg->forwards; 873 ctx->env->cfg->forwards = s->next; 874 s->next = NULL; 875 config_delstubs(s); 876 } 877 lock_basic_unlock(&ctx->cfglock); 878 return UB_NOERROR; 879 } 880 lock_basic_unlock(&ctx->cfglock); 881 882 /* check syntax for addr */ 883 if(!extstrtoaddr(addr, &storage, &stlen)) { 884 errno=EINVAL; 885 return UB_SYNTAX; 886 } 887 888 /* it parses, add root stub in front of list */ 889 lock_basic_lock(&ctx->cfglock); 890 if(!ctx->env->cfg->forwards || 891 strcmp(ctx->env->cfg->forwards->name, ".") != 0) { 892 s = calloc(1, sizeof(*s)); 893 if(!s) { 894 lock_basic_unlock(&ctx->cfglock); 895 errno=ENOMEM; 896 return UB_NOMEM; 897 } 898 s->name = strdup("."); 899 if(!s->name) { 900 free(s); 901 lock_basic_unlock(&ctx->cfglock); 902 errno=ENOMEM; 903 return UB_NOMEM; 904 } 905 s->next = ctx->env->cfg->forwards; 906 ctx->env->cfg->forwards = s; 907 } else { 908 log_assert(ctx->env->cfg->forwards); 909 s = ctx->env->cfg->forwards; 910 } 911 dupl = strdup(addr); 912 if(!dupl) { 913 lock_basic_unlock(&ctx->cfglock); 914 errno=ENOMEM; 915 return UB_NOMEM; 916 } 917 if(!cfg_strlist_insert(&s->addrs, dupl)) { 918 free(dupl); 919 lock_basic_unlock(&ctx->cfglock); 920 errno=ENOMEM; 921 return UB_NOMEM; 922 } 923 lock_basic_unlock(&ctx->cfglock); 924 return UB_NOERROR; 925 } 926 927 int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr, 928 int isprime) 929 { 930 char* a; 931 struct config_stub **prev, *elem; 932 933 /* check syntax for zone name */ 934 if(zone) { 935 uint8_t* nm; 936 int nmlabs; 937 size_t nmlen; 938 if(!parse_dname(zone, &nm, &nmlen, &nmlabs)) { 939 errno=EINVAL; 940 return UB_SYNTAX; 941 } 942 free(nm); 943 } else { 944 zone = "."; 945 } 946 947 /* check syntax for addr (if not NULL) */ 948 if(addr) { 949 struct sockaddr_storage storage; 950 socklen_t stlen; 951 if(!extstrtoaddr(addr, &storage, &stlen)) { 952 errno=EINVAL; 953 return UB_SYNTAX; 954 } 955 } 956 957 lock_basic_lock(&ctx->cfglock); 958 if(ctx->finalized) { 959 lock_basic_unlock(&ctx->cfglock); 960 errno=EINVAL; 961 return UB_AFTERFINAL; 962 } 963 964 /* arguments all right, now find or add the stub */ 965 prev = &ctx->env->cfg->stubs; 966 elem = cfg_stub_find(&prev, zone); 967 if(!elem && !addr) { 968 /* not found and we want to delete, nothing to do */ 969 lock_basic_unlock(&ctx->cfglock); 970 return UB_NOERROR; 971 } else if(elem && !addr) { 972 /* found, and we want to delete */ 973 *prev = elem->next; 974 config_delstub(elem); 975 lock_basic_unlock(&ctx->cfglock); 976 return UB_NOERROR; 977 } else if(!elem) { 978 /* not found, create the stub entry */ 979 elem=(struct config_stub*)calloc(1, sizeof(struct config_stub)); 980 if(elem) elem->name = strdup(zone); 981 if(!elem || !elem->name) { 982 free(elem); 983 lock_basic_unlock(&ctx->cfglock); 984 errno = ENOMEM; 985 return UB_NOMEM; 986 } 987 elem->next = ctx->env->cfg->stubs; 988 ctx->env->cfg->stubs = elem; 989 } 990 991 /* add the address to the list and set settings */ 992 elem->isprime = isprime; 993 a = strdup(addr); 994 if(!a) { 995 lock_basic_unlock(&ctx->cfglock); 996 errno = ENOMEM; 997 return UB_NOMEM; 998 } 999 if(!cfg_strlist_insert(&elem->addrs, a)) { 1000 lock_basic_unlock(&ctx->cfglock); 1001 free(a); 1002 errno = ENOMEM; 1003 return UB_NOMEM; 1004 } 1005 lock_basic_unlock(&ctx->cfglock); 1006 return UB_NOERROR; 1007 } 1008 1009 int 1010 ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname) 1011 { 1012 FILE* in; 1013 int numserv = 0; 1014 char buf[1024]; 1015 char* parse, *addr; 1016 int r; 1017 1018 if(fname == NULL) { 1019 #if !defined(UB_ON_WINDOWS) || !defined(HAVE_WINDOWS_H) 1020 fname = "/etc/resolv.conf"; 1021 #else 1022 FIXED_INFO *info; 1023 ULONG buflen = sizeof(*info); 1024 IP_ADDR_STRING *ptr; 1025 1026 info = (FIXED_INFO *) malloc(sizeof (FIXED_INFO)); 1027 if (info == NULL) 1028 return UB_READFILE; 1029 1030 if (GetNetworkParams(info, &buflen) == ERROR_BUFFER_OVERFLOW) { 1031 free(info); 1032 info = (FIXED_INFO *) malloc(buflen); 1033 if (info == NULL) 1034 return UB_READFILE; 1035 } 1036 1037 if (GetNetworkParams(info, &buflen) == NO_ERROR) { 1038 int retval=0; 1039 ptr = &(info->DnsServerList); 1040 while (ptr) { 1041 numserv++; 1042 if((retval=ub_ctx_set_fwd(ctx, 1043 ptr->IpAddress.String))!=0) { 1044 free(info); 1045 return retval; 1046 } 1047 ptr = ptr->Next; 1048 } 1049 free(info); 1050 if (numserv==0) 1051 return UB_READFILE; 1052 return UB_NOERROR; 1053 } 1054 free(info); 1055 return UB_READFILE; 1056 #endif /* WINDOWS */ 1057 } 1058 in = fopen(fname, "r"); 1059 if(!in) { 1060 /* error in errno! perror(fname) */ 1061 return UB_READFILE; 1062 } 1063 while(fgets(buf, (int)sizeof(buf), in)) { 1064 buf[sizeof(buf)-1] = 0; 1065 parse=buf; 1066 while(*parse == ' ' || *parse == '\t') 1067 parse++; 1068 if(strncmp(parse, "nameserver", 10) == 0) { 1069 numserv++; 1070 parse += 10; /* skip 'nameserver' */ 1071 /* skip whitespace */ 1072 while(*parse == ' ' || *parse == '\t') 1073 parse++; 1074 addr = parse; 1075 /* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */ 1076 while(isxdigit((unsigned char)*parse) || *parse=='.' || *parse==':') 1077 parse++; 1078 /* terminate after the address, remove newline */ 1079 *parse = 0; 1080 1081 if((r = ub_ctx_set_fwd(ctx, addr)) != UB_NOERROR) { 1082 fclose(in); 1083 return r; 1084 } 1085 } 1086 } 1087 fclose(in); 1088 if(numserv == 0) { 1089 /* from resolv.conf(5) if none given, use localhost */ 1090 return ub_ctx_set_fwd(ctx, "127.0.0.1"); 1091 } 1092 return UB_NOERROR; 1093 } 1094 1095 int 1096 ub_ctx_hosts(struct ub_ctx* ctx, const char* fname) 1097 { 1098 FILE* in; 1099 char buf[1024], ldata[1024]; 1100 char* parse, *addr, *name, *ins; 1101 lock_basic_lock(&ctx->cfglock); 1102 if(ctx->finalized) { 1103 lock_basic_unlock(&ctx->cfglock); 1104 errno=EINVAL; 1105 return UB_AFTERFINAL; 1106 } 1107 lock_basic_unlock(&ctx->cfglock); 1108 if(fname == NULL) { 1109 #if defined(UB_ON_WINDOWS) && defined(HAVE_WINDOWS_H) 1110 /* 1111 * If this is Windows NT/XP/2K it's in 1112 * %WINDIR%\system32\drivers\etc\hosts. 1113 * If this is Windows 95/98/Me it's in %WINDIR%\hosts. 1114 */ 1115 name = getenv("WINDIR"); 1116 if (name != NULL) { 1117 int retval=0; 1118 snprintf(buf, sizeof(buf), "%s%s", name, 1119 "\\system32\\drivers\\etc\\hosts"); 1120 if((retval=ub_ctx_hosts(ctx, buf)) !=0 ) { 1121 snprintf(buf, sizeof(buf), "%s%s", name, 1122 "\\hosts"); 1123 retval=ub_ctx_hosts(ctx, buf); 1124 } 1125 return retval; 1126 } 1127 return UB_READFILE; 1128 #else 1129 fname = "/etc/hosts"; 1130 #endif /* WIN32 */ 1131 } 1132 in = fopen(fname, "r"); 1133 if(!in) { 1134 /* error in errno! perror(fname) */ 1135 return UB_READFILE; 1136 } 1137 while(fgets(buf, (int)sizeof(buf), in)) { 1138 buf[sizeof(buf)-1] = 0; 1139 parse=buf; 1140 while(*parse == ' ' || *parse == '\t') 1141 parse++; 1142 if(*parse == '#') 1143 continue; /* skip comment */ 1144 /* format: <addr> spaces <name> spaces <name> ... */ 1145 addr = parse; 1146 /* skip addr */ 1147 while(isxdigit((unsigned char)*parse) || *parse == '.' || *parse == ':') 1148 parse++; 1149 if(*parse == '\r') 1150 parse++; 1151 if(*parse == '\n' || *parse == 0) 1152 continue; 1153 if(*parse == '%') 1154 continue; /* ignore macOSX fe80::1%lo0 localhost */ 1155 if(*parse != ' ' && *parse != '\t') { 1156 /* must have whitespace after address */ 1157 fclose(in); 1158 errno=EINVAL; 1159 return UB_SYNTAX; 1160 } 1161 *parse++ = 0; /* end delimiter for addr ... */ 1162 /* go to names and add them */ 1163 while(*parse) { 1164 while(*parse == ' ' || *parse == '\t' || *parse=='\n' 1165 || *parse=='\r') 1166 parse++; 1167 if(*parse == 0 || *parse == '#') 1168 break; 1169 /* skip name, allows (too) many printable characters */ 1170 name = parse; 1171 while('!' <= *parse && *parse <= '~') 1172 parse++; 1173 if(*parse) 1174 *parse++ = 0; /* end delimiter for name */ 1175 snprintf(ldata, sizeof(ldata), "%s %s %s", 1176 name, str_is_ip6(addr)?"AAAA":"A", addr); 1177 ins = strdup(ldata); 1178 if(!ins) { 1179 /* out of memory */ 1180 fclose(in); 1181 errno=ENOMEM; 1182 return UB_NOMEM; 1183 } 1184 lock_basic_lock(&ctx->cfglock); 1185 if(!cfg_strlist_insert(&ctx->env->cfg->local_data, 1186 ins)) { 1187 lock_basic_unlock(&ctx->cfglock); 1188 fclose(in); 1189 free(ins); 1190 errno=ENOMEM; 1191 return UB_NOMEM; 1192 } 1193 lock_basic_unlock(&ctx->cfglock); 1194 } 1195 } 1196 fclose(in); 1197 return UB_NOERROR; 1198 } 1199 1200 /** finalize the context, if not already finalized */ 1201 static int ub_ctx_finalize(struct ub_ctx* ctx) 1202 { 1203 int res = 0; 1204 lock_basic_lock(&ctx->cfglock); 1205 if (!ctx->finalized) { 1206 res = context_finalize(ctx); 1207 } 1208 lock_basic_unlock(&ctx->cfglock); 1209 return res; 1210 } 1211 1212 /* Print local zones and RR data */ 1213 int ub_ctx_print_local_zones(struct ub_ctx* ctx) 1214 { 1215 int res = ub_ctx_finalize(ctx); 1216 if (res) return res; 1217 1218 local_zones_print(ctx->local_zones); 1219 1220 return UB_NOERROR; 1221 } 1222 1223 /* Add a new zone */ 1224 int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, 1225 const char *zone_type) 1226 { 1227 enum localzone_type t; 1228 struct local_zone* z; 1229 uint8_t* nm; 1230 int nmlabs; 1231 size_t nmlen; 1232 1233 int res = ub_ctx_finalize(ctx); 1234 if (res) return res; 1235 1236 if(!local_zone_str2type(zone_type, &t)) { 1237 return UB_SYNTAX; 1238 } 1239 1240 if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) { 1241 return UB_SYNTAX; 1242 } 1243 1244 lock_rw_wrlock(&ctx->local_zones->lock); 1245 if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, 1246 LDNS_RR_CLASS_IN))) { 1247 /* already present in tree */ 1248 lock_rw_wrlock(&z->lock); 1249 z->type = t; /* update type anyway */ 1250 lock_rw_unlock(&z->lock); 1251 lock_rw_unlock(&ctx->local_zones->lock); 1252 free(nm); 1253 return UB_NOERROR; 1254 } 1255 if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs, 1256 LDNS_RR_CLASS_IN, t)) { 1257 lock_rw_unlock(&ctx->local_zones->lock); 1258 return UB_NOMEM; 1259 } 1260 lock_rw_unlock(&ctx->local_zones->lock); 1261 return UB_NOERROR; 1262 } 1263 1264 /* Remove zone */ 1265 int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name) 1266 { 1267 struct local_zone* z; 1268 uint8_t* nm; 1269 int nmlabs; 1270 size_t nmlen; 1271 1272 int res = ub_ctx_finalize(ctx); 1273 if (res) return res; 1274 1275 if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) { 1276 return UB_SYNTAX; 1277 } 1278 1279 lock_rw_wrlock(&ctx->local_zones->lock); 1280 if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, 1281 LDNS_RR_CLASS_IN))) { 1282 /* present in tree */ 1283 local_zones_del_zone(ctx->local_zones, z); 1284 } 1285 lock_rw_unlock(&ctx->local_zones->lock); 1286 free(nm); 1287 return UB_NOERROR; 1288 } 1289 1290 /* Add new RR data */ 1291 int ub_ctx_data_add(struct ub_ctx* ctx, const char *data) 1292 { 1293 int res = ub_ctx_finalize(ctx); 1294 if (res) return res; 1295 1296 res = local_zones_add_RR(ctx->local_zones, data); 1297 return (!res) ? UB_NOMEM : UB_NOERROR; 1298 } 1299 1300 /* Remove RR data */ 1301 int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data) 1302 { 1303 uint8_t* nm; 1304 int nmlabs; 1305 size_t nmlen; 1306 int res = ub_ctx_finalize(ctx); 1307 if (res) return res; 1308 1309 if(!parse_dname(data, &nm, &nmlen, &nmlabs)) 1310 return UB_SYNTAX; 1311 1312 local_zones_del_data(ctx->local_zones, nm, nmlen, nmlabs, 1313 LDNS_RR_CLASS_IN); 1314 1315 free(nm); 1316 return UB_NOERROR; 1317 } 1318 1319 const char* ub_version(void) 1320 { 1321 return PACKAGE_VERSION; 1322 } 1323 1324 int 1325 ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) { 1326 if (!ctx || !ctx->event_base || !base) { 1327 return UB_INITFAIL; 1328 } 1329 if (ctx->event_base == base) { 1330 /* already set */ 1331 return UB_NOERROR; 1332 } 1333 1334 lock_basic_lock(&ctx->cfglock); 1335 /* destroy the current worker - safe to pass in NULL */ 1336 libworker_delete_event(ctx->event_worker); 1337 ctx->event_worker = NULL; 1338 ctx->event_base = base; 1339 ctx->created_bg = 0; 1340 ctx->dothread = 1; 1341 lock_basic_unlock(&ctx->cfglock); 1342 return UB_NOERROR; 1343 } 1344