1 1.1 christos /* 2 1.1 christos * libunbound/worker.c - worker thread or process that resolves 3 1.1 christos * 4 1.1 christos * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * This software is open source. 7 1.1 christos * 8 1.1 christos * Redistribution and use in source and binary forms, with or without 9 1.1 christos * modification, are permitted provided that the following conditions 10 1.1 christos * are met: 11 1.1 christos * 12 1.1 christos * Redistributions of source code must retain the above copyright notice, 13 1.1 christos * this list of conditions and the following disclaimer. 14 1.1 christos * 15 1.1 christos * Redistributions in binary form must reproduce the above copyright notice, 16 1.1 christos * this list of conditions and the following disclaimer in the documentation 17 1.1 christos * and/or other materials provided with the distribution. 18 1.1 christos * 19 1.1 christos * Neither the name of the NLNET LABS nor the names of its contributors may 20 1.1 christos * be used to endorse or promote products derived from this software without 21 1.1 christos * specific prior written permission. 22 1.1 christos * 23 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 1.1 christos * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 1.1 christos * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 1.1 christos * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 1.1 christos * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 1.1 christos * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 1.1 christos * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 1.1 christos */ 35 1.1 christos 36 1.1 christos /** 37 1.1 christos * \file 38 1.1 christos * 39 1.1 christos * This file contains the worker process or thread that performs 40 1.1 christos * the DNS resolving and validation. The worker is called by a procedure 41 1.1 christos * and if in the background continues until exit, if in the foreground 42 1.1 christos * returns from the procedure when done. 43 1.1 christos */ 44 1.1 christos #include "config.h" 45 1.1 christos #ifdef HAVE_SSL 46 1.1 christos #include <openssl/ssl.h> 47 1.1 christos #endif 48 1.1 christos #include "libunbound/libworker.h" 49 1.1 christos #include "libunbound/context.h" 50 1.1 christos #include "libunbound/unbound.h" 51 1.1 christos #include "libunbound/worker.h" 52 1.1 christos #include "libunbound/unbound-event.h" 53 1.1 christos #include "services/outside_network.h" 54 1.1 christos #include "services/mesh.h" 55 1.1 christos #include "services/localzone.h" 56 1.1 christos #include "services/cache/rrset.h" 57 1.1 christos #include "services/outbound_list.h" 58 1.1.1.3 christos #include "services/authzone.h" 59 1.1 christos #include "util/fptr_wlist.h" 60 1.1 christos #include "util/module.h" 61 1.1 christos #include "util/regional.h" 62 1.1 christos #include "util/random.h" 63 1.1 christos #include "util/config_file.h" 64 1.1 christos #include "util/netevent.h" 65 1.1.1.8 christos #include "util/proxy_protocol.h" 66 1.1 christos #include "util/storage/lookup3.h" 67 1.1 christos #include "util/storage/slabhash.h" 68 1.1 christos #include "util/net_help.h" 69 1.1 christos #include "util/data/dname.h" 70 1.1 christos #include "util/data/msgreply.h" 71 1.1 christos #include "util/data/msgencode.h" 72 1.1 christos #include "util/tube.h" 73 1.1 christos #include "sldns/sbuffer.h" 74 1.1 christos #include "sldns/str2wire.h" 75 1.1.1.6 christos #ifdef USE_DNSTAP 76 1.1.1.6 christos #include "dnstap/dtstream.h" 77 1.1.1.6 christos #endif 78 1.1.1.6 christos 79 1.1.1.6 christos #ifdef HAVE_TARGETCONDITIONALS_H 80 1.1.1.6 christos #include <TargetConditionals.h> 81 1.1.1.6 christos #endif 82 1.1.1.6 christos 83 1.1.1.6 christos #if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) 84 1.1.1.6 christos #undef HAVE_FORK 85 1.1.1.6 christos #endif 86 1.1 christos 87 1.1 christos /** handle new query command for bg worker */ 88 1.1 christos static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len); 89 1.1 christos 90 1.1 christos /** delete libworker env */ 91 1.1 christos static void 92 1.1 christos libworker_delete_env(struct libworker* w) 93 1.1 christos { 94 1.1 christos if(w->env) { 95 1.1 christos outside_network_quit_prepare(w->back); 96 1.1 christos mesh_delete(w->env->mesh); 97 1.1 christos context_release_alloc(w->ctx, w->env->alloc, 98 1.1 christos !w->is_bg || w->is_bg_thread); 99 1.1 christos sldns_buffer_free(w->env->scratch_buffer); 100 1.1 christos regional_destroy(w->env->scratch); 101 1.1 christos ub_randfree(w->env->rnd); 102 1.1 christos free(w->env); 103 1.1 christos } 104 1.1 christos #ifdef HAVE_SSL 105 1.1 christos SSL_CTX_free(w->sslctx); 106 1.1 christos #endif 107 1.1 christos outside_network_delete(w->back); 108 1.1 christos } 109 1.1 christos 110 1.1 christos /** delete libworker struct */ 111 1.1 christos static void 112 1.1 christos libworker_delete(struct libworker* w) 113 1.1 christos { 114 1.1 christos if(!w) return; 115 1.1 christos libworker_delete_env(w); 116 1.1 christos comm_base_delete(w->base); 117 1.1 christos free(w); 118 1.1 christos } 119 1.1 christos 120 1.1 christos void 121 1.1 christos libworker_delete_event(struct libworker* w) 122 1.1 christos { 123 1.1 christos if(!w) return; 124 1.1 christos libworker_delete_env(w); 125 1.1 christos comm_base_delete_no_base(w->base); 126 1.1 christos free(w); 127 1.1 christos } 128 1.1 christos 129 1.1 christos /** setup fresh libworker struct */ 130 1.1 christos static struct libworker* 131 1.1 christos libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) 132 1.1 christos { 133 1.1 christos struct libworker* w = (struct libworker*)calloc(1, sizeof(*w)); 134 1.1 christos struct config_file* cfg = ctx->env->cfg; 135 1.1 christos int* ports; 136 1.1 christos int numports; 137 1.1 christos if(!w) return NULL; 138 1.1 christos w->is_bg = is_bg; 139 1.1 christos w->ctx = ctx; 140 1.1 christos w->env = (struct module_env*)malloc(sizeof(*w->env)); 141 1.1 christos if(!w->env) { 142 1.1 christos free(w); 143 1.1 christos return NULL; 144 1.1 christos } 145 1.1 christos *w->env = *ctx->env; 146 1.1 christos w->env->alloc = context_obtain_alloc(ctx, !w->is_bg || w->is_bg_thread); 147 1.1 christos if(!w->env->alloc) { 148 1.1 christos libworker_delete(w); 149 1.1 christos return NULL; 150 1.1 christos } 151 1.1 christos w->thread_num = w->env->alloc->thread_num; 152 1.1 christos alloc_set_id_cleanup(w->env->alloc, &libworker_alloc_cleanup, w); 153 1.1 christos if(!w->is_bg || w->is_bg_thread) { 154 1.1 christos lock_basic_lock(&ctx->cfglock); 155 1.1 christos } 156 1.1 christos w->env->scratch = regional_create_custom(cfg->msg_buffer_size); 157 1.1 christos w->env->scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size); 158 1.1.1.8 christos #ifdef HAVE_SSL 159 1.1.1.8 christos w->sslctx = connect_sslctx_create(NULL, NULL, 160 1.1.1.8 christos cfg->tls_cert_bundle, cfg->tls_win_cert); 161 1.1.1.8 christos if(!w->sslctx) { 162 1.1.1.8 christos /* to make the setup fail after unlock */ 163 1.1.1.9 christos sldns_buffer_free(w->env->scratch_buffer); 164 1.1.1.9 christos w->env->scratch_buffer = NULL; 165 1.1 christos } 166 1.1.1.8 christos #endif 167 1.1 christos if(!w->is_bg || w->is_bg_thread) { 168 1.1 christos lock_basic_unlock(&ctx->cfglock); 169 1.1 christos } 170 1.1.1.9 christos if(!w->env->scratch || !w->env->scratch_buffer) { 171 1.1 christos libworker_delete(w); 172 1.1 christos return NULL; 173 1.1 christos } 174 1.1 christos w->env->worker = (struct worker*)w; 175 1.1 christos w->env->probe_timer = NULL; 176 1.1 christos if(!w->is_bg || w->is_bg_thread) { 177 1.1 christos lock_basic_lock(&ctx->cfglock); 178 1.1 christos } 179 1.1.1.5 christos if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) { 180 1.1 christos if(!w->is_bg || w->is_bg_thread) { 181 1.1 christos lock_basic_unlock(&ctx->cfglock); 182 1.1 christos } 183 1.1 christos libworker_delete(w); 184 1.1 christos return NULL; 185 1.1 christos } 186 1.1 christos if(!w->is_bg || w->is_bg_thread) { 187 1.1 christos lock_basic_unlock(&ctx->cfglock); 188 1.1 christos } 189 1.1 christos if(1) { 190 1.1 christos /* primitive lockout for threading: if it overwrites another 191 1.1 christos * thread it is like wiping the cache (which is likely empty 192 1.1 christos * at the start) */ 193 1.1 christos /* note we are holding the ctx lock in normal threaded 194 1.1 christos * cases so that is solved properly, it is only for many ctx 195 1.1 christos * in different threads that this may clash */ 196 1.1 christos static int done_raninit = 0; 197 1.1 christos if(!done_raninit) { 198 1.1 christos done_raninit = 1; 199 1.1 christos hash_set_raninit((uint32_t)ub_random(w->env->rnd)); 200 1.1 christos } 201 1.1 christos } 202 1.1 christos 203 1.1 christos if(eb) 204 1.1 christos w->base = comm_base_create_event(eb); 205 1.1 christos else w->base = comm_base_create(0); 206 1.1 christos if(!w->base) { 207 1.1 christos libworker_delete(w); 208 1.1 christos return NULL; 209 1.1 christos } 210 1.1.1.3 christos w->env->worker_base = w->base; 211 1.1 christos if(!w->is_bg || w->is_bg_thread) { 212 1.1 christos lock_basic_lock(&ctx->cfglock); 213 1.1 christos } 214 1.1 christos numports = cfg_condense_ports(cfg, &ports); 215 1.1 christos if(numports == 0) { 216 1.1.1.4 christos if(!w->is_bg || w->is_bg_thread) { 217 1.1 christos lock_basic_unlock(&ctx->cfglock); 218 1.1 christos } 219 1.1.1.4 christos libworker_delete(w); 220 1.1 christos return NULL; 221 1.1 christos } 222 1.1 christos w->back = outside_network_create(w->base, cfg->msg_buffer_size, 223 1.1 christos (size_t)cfg->outgoing_num_ports, cfg->out_ifs, 224 1.1 christos cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, 225 1.1.1.6 christos cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp, 226 1.1 christos w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id, 227 1.1 christos ports, numports, cfg->unwanted_threshold, 228 1.1.1.2 christos cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w, 229 1.1.1.2 christos cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx, 230 1.1.1.7 christos cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect, 231 1.1.1.7 christos cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout, 232 1.1.1.7 christos cfg->tcp_auth_query_timeout); 233 1.1.1.3 christos w->env->outnet = w->back; 234 1.1 christos if(!w->is_bg || w->is_bg_thread) { 235 1.1 christos lock_basic_unlock(&ctx->cfglock); 236 1.1 christos } 237 1.1 christos free(ports); 238 1.1 christos if(!w->back) { 239 1.1 christos libworker_delete(w); 240 1.1 christos return NULL; 241 1.1 christos } 242 1.1 christos w->env->mesh = mesh_create(&ctx->mods, w->env); 243 1.1 christos if(!w->env->mesh) { 244 1.1 christos libworker_delete(w); 245 1.1 christos return NULL; 246 1.1 christos } 247 1.1 christos w->env->send_query = &libworker_send_query; 248 1.1 christos w->env->detach_subs = &mesh_detach_subs; 249 1.1 christos w->env->attach_sub = &mesh_attach_sub; 250 1.1.1.2 christos w->env->add_sub = &mesh_add_sub; 251 1.1 christos w->env->kill_sub = &mesh_state_delete; 252 1.1 christos w->env->detect_cycle = &mesh_detect_cycle; 253 1.1 christos comm_base_timept(w->base, &w->env->now, &w->env->now_tv); 254 1.1.1.8 christos pp_init(&sldns_write_uint16, &sldns_write_uint32); 255 1.1 christos return w; 256 1.1 christos } 257 1.1 christos 258 1.1 christos struct libworker* libworker_create_event(struct ub_ctx* ctx, 259 1.1 christos struct ub_event_base* eb) 260 1.1 christos { 261 1.1 christos return libworker_setup(ctx, 0, eb); 262 1.1 christos } 263 1.1 christos 264 1.1 christos /** handle cancel command for bg worker */ 265 1.1 christos static void 266 1.1 christos handle_cancel(struct libworker* w, uint8_t* buf, uint32_t len) 267 1.1 christos { 268 1.1 christos struct ctx_query* q; 269 1.1 christos if(w->is_bg_thread) { 270 1.1 christos lock_basic_lock(&w->ctx->cfglock); 271 1.1 christos q = context_deserialize_cancel(w->ctx, buf, len); 272 1.1 christos lock_basic_unlock(&w->ctx->cfglock); 273 1.1 christos } else { 274 1.1 christos q = context_deserialize_cancel(w->ctx, buf, len); 275 1.1 christos } 276 1.1 christos if(!q) { 277 1.1 christos /* probably simply lookup failed, i.e. the message had been 278 1.1 christos * processed and answered before the cancel arrived */ 279 1.1 christos return; 280 1.1 christos } 281 1.1 christos q->cancelled = 1; 282 1.1 christos free(buf); 283 1.1 christos } 284 1.1 christos 285 1.1 christos /** do control command coming into bg server */ 286 1.1 christos static void 287 1.1 christos libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len) 288 1.1 christos { 289 1.1 christos switch(context_serial_getcmd(msg, len)) { 290 1.1 christos default: 291 1.1 christos case UB_LIBCMD_ANSWER: 292 1.1 christos log_err("unknown command for bg worker %d", 293 1.1 christos (int)context_serial_getcmd(msg, len)); 294 1.1 christos /* and fall through to quit */ 295 1.1.1.9 christos ATTR_FALLTHROUGH 296 1.1.1.2 christos /* fallthrough */ 297 1.1 christos case UB_LIBCMD_QUIT: 298 1.1 christos free(msg); 299 1.1 christos comm_base_exit(w->base); 300 1.1 christos break; 301 1.1 christos case UB_LIBCMD_NEWQUERY: 302 1.1 christos handle_newq(w, msg, len); 303 1.1 christos break; 304 1.1 christos case UB_LIBCMD_CANCEL: 305 1.1 christos handle_cancel(w, msg, len); 306 1.1 christos break; 307 1.1 christos } 308 1.1 christos } 309 1.1 christos 310 1.1 christos /** handle control command coming into server */ 311 1.1 christos void 312 1.1 christos libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), 313 1.1 christos uint8_t* msg, size_t len, int err, void* arg) 314 1.1 christos { 315 1.1 christos struct libworker* w = (struct libworker*)arg; 316 1.1 christos 317 1.1 christos if(err != 0) { 318 1.1 christos free(msg); 319 1.1 christos /* it is of no use to go on, exit */ 320 1.1 christos comm_base_exit(w->base); 321 1.1 christos return; 322 1.1 christos } 323 1.1 christos libworker_do_cmd(w, msg, len); /* also frees the buf */ 324 1.1 christos } 325 1.1 christos 326 1.1 christos /** the background thread func */ 327 1.1 christos static void* 328 1.1 christos libworker_dobg(void* arg) 329 1.1 christos { 330 1.1 christos /* setup */ 331 1.1 christos uint32_t m; 332 1.1 christos struct libworker* w = (struct libworker*)arg; 333 1.1 christos struct ub_ctx* ctx; 334 1.1 christos if(!w) { 335 1.1 christos log_err("libunbound bg worker init failed, nomem"); 336 1.1 christos return NULL; 337 1.1 christos } 338 1.1 christos ctx = w->ctx; 339 1.1 christos log_thread_set(&w->thread_num); 340 1.1 christos #ifdef THREADS_DISABLED 341 1.1 christos /* we are forked */ 342 1.1 christos w->is_bg_thread = 0; 343 1.1 christos /* close non-used parts of the pipes */ 344 1.1 christos tube_close_write(ctx->qq_pipe); 345 1.1 christos tube_close_read(ctx->rr_pipe); 346 1.1 christos #endif 347 1.1 christos if(!tube_setup_bg_listen(ctx->qq_pipe, w->base, 348 1.1 christos libworker_handle_control_cmd, w)) { 349 1.1 christos log_err("libunbound bg worker init failed, no bglisten"); 350 1.1 christos return NULL; 351 1.1 christos } 352 1.1 christos if(!tube_setup_bg_write(ctx->rr_pipe, w->base)) { 353 1.1 christos log_err("libunbound bg worker init failed, no bgwrite"); 354 1.1 christos return NULL; 355 1.1 christos } 356 1.1 christos 357 1.1 christos /* do the work */ 358 1.1 christos comm_base_dispatch(w->base); 359 1.1 christos 360 1.1 christos /* cleanup */ 361 1.1 christos m = UB_LIBCMD_QUIT; 362 1.1.1.3 christos w->want_quit = 1; 363 1.1 christos tube_remove_bg_listen(w->ctx->qq_pipe); 364 1.1 christos tube_remove_bg_write(w->ctx->rr_pipe); 365 1.1 christos libworker_delete(w); 366 1.1 christos (void)tube_write_msg(ctx->rr_pipe, (uint8_t*)&m, 367 1.1 christos (uint32_t)sizeof(m), 0); 368 1.1 christos #ifdef THREADS_DISABLED 369 1.1 christos /* close pipes from forked process before exit */ 370 1.1 christos tube_close_read(ctx->qq_pipe); 371 1.1 christos tube_close_write(ctx->rr_pipe); 372 1.1 christos #endif 373 1.1 christos return NULL; 374 1.1 christos } 375 1.1 christos 376 1.1 christos int libworker_bg(struct ub_ctx* ctx) 377 1.1 christos { 378 1.1 christos struct libworker* w; 379 1.1 christos /* fork or threadcreate */ 380 1.1 christos lock_basic_lock(&ctx->cfglock); 381 1.1 christos if(ctx->dothread) { 382 1.1 christos lock_basic_unlock(&ctx->cfglock); 383 1.1 christos w = libworker_setup(ctx, 1, NULL); 384 1.1 christos if(!w) return UB_NOMEM; 385 1.1 christos w->is_bg_thread = 1; 386 1.1.1.8 christos ctx->thread_worker = w; 387 1.1 christos #ifdef ENABLE_LOCK_CHECKS 388 1.1 christos w->thread_num = 1; /* for nicer DEBUG checklocks */ 389 1.1 christos #endif 390 1.1 christos ub_thread_create(&ctx->bg_tid, libworker_dobg, w); 391 1.1 christos } else { 392 1.1 christos lock_basic_unlock(&ctx->cfglock); 393 1.1 christos #ifndef HAVE_FORK 394 1.1 christos /* no fork on windows */ 395 1.1 christos return UB_FORKFAIL; 396 1.1 christos #else /* HAVE_FORK */ 397 1.1 christos switch((ctx->bg_pid=fork())) { 398 1.1 christos case 0: 399 1.1 christos w = libworker_setup(ctx, 1, NULL); 400 1.1 christos if(!w) fatal_exit("out of memory"); 401 1.1 christos /* close non-used parts of the pipes */ 402 1.1 christos tube_close_write(ctx->qq_pipe); 403 1.1 christos tube_close_read(ctx->rr_pipe); 404 1.1 christos (void)libworker_dobg(w); 405 1.1 christos exit(0); 406 1.1 christos break; 407 1.1 christos case -1: 408 1.1 christos return UB_FORKFAIL; 409 1.1 christos default: 410 1.1 christos /* close non-used parts, so that the worker 411 1.1 christos * bgprocess gets 'pipe closed' when the 412 1.1 christos * main process exits */ 413 1.1 christos tube_close_read(ctx->qq_pipe); 414 1.1 christos tube_close_write(ctx->rr_pipe); 415 1.1 christos break; 416 1.1 christos } 417 1.1 christos #endif /* HAVE_FORK */ 418 1.1 christos } 419 1.1 christos return UB_NOERROR; 420 1.1 christos } 421 1.1 christos 422 1.1 christos /** insert canonname */ 423 1.1 christos static int 424 1.1 christos fill_canon(struct ub_result* res, uint8_t* s) 425 1.1 christos { 426 1.1.1.9 christos char buf[LDNS_MAX_DOMAINLEN]; 427 1.1 christos dname_str(s, buf); 428 1.1 christos res->canonname = strdup(buf); 429 1.1 christos return res->canonname != 0; 430 1.1 christos } 431 1.1 christos 432 1.1 christos /** fill data into result */ 433 1.1 christos static int 434 1.1 christos fill_res(struct ub_result* res, struct ub_packed_rrset_key* answer, 435 1.1 christos uint8_t* finalcname, struct query_info* rq, struct reply_info* rep) 436 1.1 christos { 437 1.1 christos size_t i; 438 1.1 christos struct packed_rrset_data* data; 439 1.1 christos res->ttl = 0; 440 1.1 christos if(!answer) { 441 1.1 christos if(finalcname) { 442 1.1 christos if(!fill_canon(res, finalcname)) 443 1.1 christos return 0; /* out of memory */ 444 1.1 christos } 445 1.1 christos if(rep->rrset_count != 0) 446 1.1 christos res->ttl = (int)rep->ttl; 447 1.1 christos res->data = (char**)calloc(1, sizeof(char*)); 448 1.1.1.7 christos if(!res->data) 449 1.1.1.7 christos return 0; /* out of memory */ 450 1.1 christos res->len = (int*)calloc(1, sizeof(int)); 451 1.1.1.7 christos if(!res->len) { 452 1.1.1.7 christos free(res->data); 453 1.1.1.7 christos res->data = NULL; 454 1.1.1.7 christos return 0; /* out of memory */ 455 1.1.1.7 christos } 456 1.1.1.7 christos return 1; 457 1.1 christos } 458 1.1 christos data = (struct packed_rrset_data*)answer->entry.data; 459 1.1 christos if(query_dname_compare(rq->qname, answer->rk.dname) != 0) { 460 1.1 christos if(!fill_canon(res, answer->rk.dname)) 461 1.1 christos return 0; /* out of memory */ 462 1.1 christos } else res->canonname = NULL; 463 1.1 christos res->data = (char**)calloc(data->count+1, sizeof(char*)); 464 1.1.1.7 christos if(!res->data) 465 1.1.1.7 christos return 0; /* out of memory */ 466 1.1 christos res->len = (int*)calloc(data->count+1, sizeof(int)); 467 1.1.1.7 christos if(!res->len) { 468 1.1.1.7 christos free(res->data); 469 1.1.1.7 christos res->data = NULL; 470 1.1 christos return 0; /* out of memory */ 471 1.1.1.7 christos } 472 1.1 christos for(i=0; i<data->count; i++) { 473 1.1 christos /* remove rdlength from rdata */ 474 1.1 christos res->len[i] = (int)(data->rr_len[i] - 2); 475 1.1 christos res->data[i] = memdup(data->rr_data[i]+2, (size_t)res->len[i]); 476 1.1.1.7 christos if(!res->data[i]) { 477 1.1.1.7 christos size_t j; 478 1.1.1.7 christos for(j=0; j<i; j++) { 479 1.1.1.7 christos free(res->data[j]); 480 1.1.1.7 christos res->data[j] = NULL; 481 1.1.1.7 christos } 482 1.1.1.7 christos free(res->data); 483 1.1.1.7 christos res->data = NULL; 484 1.1.1.7 christos free(res->len); 485 1.1.1.7 christos res->len = NULL; 486 1.1 christos return 0; /* out of memory */ 487 1.1.1.7 christos } 488 1.1 christos } 489 1.1 christos /* ttl for positive answers, from CNAME and answer RRs */ 490 1.1 christos if(data->count != 0) { 491 1.1 christos size_t j; 492 1.1 christos res->ttl = (int)data->ttl; 493 1.1 christos for(j=0; j<rep->an_numrrsets; j++) { 494 1.1 christos struct packed_rrset_data* d = 495 1.1 christos (struct packed_rrset_data*)rep->rrsets[j]-> 496 1.1 christos entry.data; 497 1.1 christos if((int)d->ttl < res->ttl) 498 1.1 christos res->ttl = (int)d->ttl; 499 1.1 christos } 500 1.1 christos } 501 1.1 christos /* ttl for negative answers */ 502 1.1 christos if(data->count == 0 && rep->rrset_count != 0) 503 1.1 christos res->ttl = (int)rep->ttl; 504 1.1 christos res->data[data->count] = NULL; 505 1.1 christos res->len[data->count] = 0; 506 1.1 christos return 1; 507 1.1 christos } 508 1.1 christos 509 1.1 christos /** fill result from parsed message, on error fills servfail */ 510 1.1 christos void 511 1.1 christos libworker_enter_result(struct ub_result* res, sldns_buffer* buf, 512 1.1 christos struct regional* temp, enum sec_status msg_security) 513 1.1 christos { 514 1.1 christos struct query_info rq; 515 1.1 christos struct reply_info* rep; 516 1.1 christos res->rcode = LDNS_RCODE_SERVFAIL; 517 1.1.1.3 christos rep = parse_reply_in_temp_region(buf, temp, &rq); 518 1.1 christos if(!rep) { 519 1.1 christos log_err("cannot parse buf"); 520 1.1 christos return; /* error parsing buf, or out of memory */ 521 1.1 christos } 522 1.1 christos if(!fill_res(res, reply_find_answer_rrset(&rq, rep), 523 1.1 christos reply_find_final_cname_target(&rq, rep), &rq, rep)) 524 1.1 christos return; /* out of memory */ 525 1.1 christos /* rcode, havedata, nxdomain, secure, bogus */ 526 1.1 christos res->rcode = (int)FLAGS_GET_RCODE(rep->flags); 527 1.1 christos if(res->data && res->data[0]) 528 1.1 christos res->havedata = 1; 529 1.1 christos if(res->rcode == LDNS_RCODE_NXDOMAIN) 530 1.1 christos res->nxdomain = 1; 531 1.1 christos if(msg_security == sec_status_secure) 532 1.1 christos res->secure = 1; 533 1.1.1.3 christos if(msg_security == sec_status_bogus || 534 1.1.1.3 christos msg_security == sec_status_secure_sentinel_fail) 535 1.1 christos res->bogus = 1; 536 1.1 christos } 537 1.1 christos 538 1.1 christos /** fillup fg results */ 539 1.1 christos static void 540 1.1 christos libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf, 541 1.1.1.4 christos enum sec_status s, char* why_bogus, int was_ratelimited) 542 1.1 christos { 543 1.1.1.4 christos q->res->was_ratelimited = was_ratelimited; 544 1.1 christos if(why_bogus) 545 1.1 christos q->res->why_bogus = strdup(why_bogus); 546 1.1 christos if(rcode != 0) { 547 1.1 christos q->res->rcode = rcode; 548 1.1 christos q->msg_security = s; 549 1.1 christos return; 550 1.1 christos } 551 1.1 christos 552 1.1 christos q->res->rcode = LDNS_RCODE_SERVFAIL; 553 1.1.1.5 christos q->msg_security = sec_status_unchecked; 554 1.1 christos q->msg = memdup(sldns_buffer_begin(buf), sldns_buffer_limit(buf)); 555 1.1 christos q->msg_len = sldns_buffer_limit(buf); 556 1.1 christos if(!q->msg) { 557 1.1 christos return; /* the error is in the rcode */ 558 1.1 christos } 559 1.1 christos 560 1.1 christos /* canonname and results */ 561 1.1 christos q->msg_security = s; 562 1.1 christos libworker_enter_result(q->res, buf, q->w->env->scratch, s); 563 1.1 christos } 564 1.1 christos 565 1.1 christos void 566 1.1 christos libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, 567 1.1.1.4 christos char* why_bogus, int was_ratelimited) 568 1.1 christos { 569 1.1 christos struct ctx_query* q = (struct ctx_query*)arg; 570 1.1 christos /* fg query is done; exit comm base */ 571 1.1 christos comm_base_exit(q->w->base); 572 1.1 christos 573 1.1.1.4 christos libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited); 574 1.1 christos } 575 1.1 christos 576 1.1 christos /** setup qinfo and edns */ 577 1.1 christos static int 578 1.1 christos setup_qinfo_edns(struct libworker* w, struct ctx_query* q, 579 1.1 christos struct query_info* qinfo, struct edns_data* edns) 580 1.1 christos { 581 1.1 christos qinfo->qtype = (uint16_t)q->res->qtype; 582 1.1 christos qinfo->qclass = (uint16_t)q->res->qclass; 583 1.1.1.2 christos qinfo->local_alias = NULL; 584 1.1 christos qinfo->qname = sldns_str2wire_dname(q->res->qname, &qinfo->qname_len); 585 1.1 christos if(!qinfo->qname) { 586 1.1 christos return 0; 587 1.1 christos } 588 1.1 christos edns->edns_present = 1; 589 1.1 christos edns->ext_rcode = 0; 590 1.1 christos edns->edns_version = 0; 591 1.1 christos edns->bits = EDNS_DO; 592 1.1.1.7 christos edns->opt_list_in = NULL; 593 1.1.1.7 christos edns->opt_list_out = NULL; 594 1.1.1.7 christos edns->opt_list_inplace_cb_out = NULL; 595 1.1.1.6 christos edns->padding_block_size = 0; 596 1.1.1.8 christos edns->cookie_present = 0; 597 1.1.1.8 christos edns->cookie_valid = 0; 598 1.1 christos if(sldns_buffer_capacity(w->back->udp_buff) < 65535) 599 1.1 christos edns->udp_size = (uint16_t)sldns_buffer_capacity( 600 1.1 christos w->back->udp_buff); 601 1.1 christos else edns->udp_size = 65535; 602 1.1 christos return 1; 603 1.1 christos } 604 1.1 christos 605 1.1 christos int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) 606 1.1 christos { 607 1.1 christos struct libworker* w = libworker_setup(ctx, 0, NULL); 608 1.1 christos uint16_t qflags, qid; 609 1.1 christos struct query_info qinfo; 610 1.1 christos struct edns_data edns; 611 1.1 christos if(!w) 612 1.1 christos return UB_INITFAIL; 613 1.1 christos if(!setup_qinfo_edns(w, q, &qinfo, &edns)) { 614 1.1 christos libworker_delete(w); 615 1.1 christos return UB_SYNTAX; 616 1.1 christos } 617 1.1 christos qid = 0; 618 1.1 christos qflags = BIT_RD; 619 1.1 christos q->w = w; 620 1.1 christos /* see if there is a fixed answer */ 621 1.1 christos sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); 622 1.1 christos sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); 623 1.1.1.2 christos if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns, 624 1.1.1.2 christos w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0, 625 1.1.1.2 christos NULL, 0, NULL, 0, NULL)) { 626 1.1 christos regional_free_all(w->env->scratch); 627 1.1 christos libworker_fillup_fg(q, LDNS_RCODE_NOERROR, 628 1.1.1.4 christos w->back->udp_buff, sec_status_insecure, NULL, 0); 629 1.1 christos libworker_delete(w); 630 1.1 christos free(qinfo.qname); 631 1.1 christos return UB_NOERROR; 632 1.1 christos } 633 1.1.1.10 christos if(ctx->env->auth_zones && auth_zones_downstream_answer( 634 1.1.1.10 christos ctx->env->auth_zones, w->env, &qinfo, &edns, NULL, 635 1.1.1.10 christos w->back->udp_buff, w->env->scratch)) { 636 1.1.1.3 christos regional_free_all(w->env->scratch); 637 1.1.1.3 christos libworker_fillup_fg(q, LDNS_RCODE_NOERROR, 638 1.1.1.4 christos w->back->udp_buff, sec_status_insecure, NULL, 0); 639 1.1.1.3 christos libworker_delete(w); 640 1.1.1.3 christos free(qinfo.qname); 641 1.1.1.3 christos return UB_NOERROR; 642 1.1.1.3 christos } 643 1.1 christos /* process new query */ 644 1.1 christos if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, 645 1.1.1.7 christos w->back->udp_buff, qid, libworker_fg_done_cb, q, 0)) { 646 1.1 christos free(qinfo.qname); 647 1.1 christos return UB_NOMEM; 648 1.1 christos } 649 1.1 christos free(qinfo.qname); 650 1.1 christos 651 1.1 christos /* wait for reply */ 652 1.1 christos comm_base_dispatch(w->base); 653 1.1 christos 654 1.1 christos libworker_delete(w); 655 1.1 christos return UB_NOERROR; 656 1.1 christos } 657 1.1 christos 658 1.1 christos void 659 1.1 christos libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf, 660 1.1.1.4 christos enum sec_status s, char* why_bogus, int was_ratelimited) 661 1.1 christos { 662 1.1 christos struct ctx_query* q = (struct ctx_query*)arg; 663 1.1.1.3 christos ub_event_callback_type cb = q->cb_event; 664 1.1 christos void* cb_arg = q->cb_arg; 665 1.1 christos int cancelled = q->cancelled; 666 1.1 christos 667 1.1 christos /* delete it now */ 668 1.1 christos struct ub_ctx* ctx = q->w->ctx; 669 1.1 christos lock_basic_lock(&ctx->cfglock); 670 1.1 christos (void)rbtree_delete(&ctx->queries, q->node.key); 671 1.1 christos ctx->num_async--; 672 1.1 christos context_query_delete(q); 673 1.1 christos lock_basic_unlock(&ctx->cfglock); 674 1.1 christos 675 1.1 christos if(!cancelled) { 676 1.1 christos /* call callback */ 677 1.1 christos int sec = 0; 678 1.1 christos if(s == sec_status_bogus) 679 1.1 christos sec = 1; 680 1.1 christos else if(s == sec_status_secure) 681 1.1 christos sec = 2; 682 1.1.1.4 christos (*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL), 683 1.1.1.4 christos (buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited); 684 1.1 christos } 685 1.1 christos } 686 1.1 christos 687 1.1 christos int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, 688 1.1 christos int* async_id) 689 1.1 christos { 690 1.1 christos struct libworker* w = ctx->event_worker; 691 1.1 christos uint16_t qflags, qid; 692 1.1 christos struct query_info qinfo; 693 1.1 christos struct edns_data edns; 694 1.1 christos if(!w) 695 1.1 christos return UB_INITFAIL; 696 1.1 christos if(!setup_qinfo_edns(w, q, &qinfo, &edns)) 697 1.1 christos return UB_SYNTAX; 698 1.1 christos qid = 0; 699 1.1 christos qflags = BIT_RD; 700 1.1 christos q->w = w; 701 1.1 christos /* see if there is a fixed answer */ 702 1.1 christos sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); 703 1.1 christos sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); 704 1.1.1.2 christos if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns, 705 1.1.1.2 christos w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0, 706 1.1.1.2 christos NULL, 0, NULL, 0, NULL)) { 707 1.1 christos regional_free_all(w->env->scratch); 708 1.1 christos free(qinfo.qname); 709 1.1 christos libworker_event_done_cb(q, LDNS_RCODE_NOERROR, 710 1.1.1.4 christos w->back->udp_buff, sec_status_insecure, NULL, 0); 711 1.1 christos return UB_NOERROR; 712 1.1 christos } 713 1.1.1.10 christos if(ctx->env->auth_zones && auth_zones_downstream_answer( 714 1.1.1.10 christos ctx->env->auth_zones, w->env, &qinfo, &edns, NULL, 715 1.1.1.10 christos w->back->udp_buff, w->env->scratch)) { 716 1.1.1.3 christos regional_free_all(w->env->scratch); 717 1.1.1.3 christos free(qinfo.qname); 718 1.1.1.3 christos libworker_event_done_cb(q, LDNS_RCODE_NOERROR, 719 1.1.1.4 christos w->back->udp_buff, sec_status_insecure, NULL, 0); 720 1.1.1.3 christos return UB_NOERROR; 721 1.1.1.3 christos } 722 1.1 christos /* process new query */ 723 1.1 christos if(async_id) 724 1.1 christos *async_id = q->querynum; 725 1.1 christos if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, 726 1.1.1.7 christos w->back->udp_buff, qid, libworker_event_done_cb, q, 0)) { 727 1.1 christos free(qinfo.qname); 728 1.1 christos return UB_NOMEM; 729 1.1 christos } 730 1.1 christos free(qinfo.qname); 731 1.1 christos return UB_NOERROR; 732 1.1 christos } 733 1.1 christos 734 1.1 christos /** add result to the bg worker result queue */ 735 1.1 christos static void 736 1.1 christos add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt, 737 1.1.1.4 christos int err, char* reason, int was_ratelimited) 738 1.1 christos { 739 1.1 christos uint8_t* msg = NULL; 740 1.1 christos uint32_t len = 0; 741 1.1 christos 742 1.1.1.3 christos if(w->want_quit) { 743 1.1.1.3 christos context_query_delete(q); 744 1.1.1.3 christos return; 745 1.1.1.3 christos } 746 1.1 christos /* serialize and delete unneeded q */ 747 1.1 christos if(w->is_bg_thread) { 748 1.1 christos lock_basic_lock(&w->ctx->cfglock); 749 1.1 christos if(reason) 750 1.1 christos q->res->why_bogus = strdup(reason); 751 1.1.1.4 christos q->res->was_ratelimited = was_ratelimited; 752 1.1 christos if(pkt) { 753 1.1 christos q->msg_len = sldns_buffer_remaining(pkt); 754 1.1 christos q->msg = memdup(sldns_buffer_begin(pkt), q->msg_len); 755 1.1.1.4 christos if(!q->msg) { 756 1.1.1.4 christos msg = context_serialize_answer(q, UB_NOMEM, NULL, &len); 757 1.1.1.4 christos } else { 758 1.1.1.4 christos msg = context_serialize_answer(q, err, NULL, &len); 759 1.1.1.4 christos } 760 1.1.1.4 christos } else { 761 1.1.1.4 christos msg = context_serialize_answer(q, err, NULL, &len); 762 1.1.1.4 christos } 763 1.1 christos lock_basic_unlock(&w->ctx->cfglock); 764 1.1 christos } else { 765 1.1 christos if(reason) 766 1.1 christos q->res->why_bogus = strdup(reason); 767 1.1.1.4 christos q->res->was_ratelimited = was_ratelimited; 768 1.1 christos msg = context_serialize_answer(q, err, pkt, &len); 769 1.1 christos (void)rbtree_delete(&w->ctx->queries, q->node.key); 770 1.1 christos w->ctx->num_async--; 771 1.1 christos context_query_delete(q); 772 1.1 christos } 773 1.1 christos 774 1.1 christos if(!msg) { 775 1.1 christos log_err("out of memory for async answer"); 776 1.1 christos return; 777 1.1 christos } 778 1.1 christos if(!tube_queue_item(w->ctx->rr_pipe, msg, len)) { 779 1.1 christos log_err("out of memory for async answer"); 780 1.1 christos return; 781 1.1 christos } 782 1.1 christos } 783 1.1 christos 784 1.1 christos void 785 1.1 christos libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s, 786 1.1.1.4 christos char* why_bogus, int was_ratelimited) 787 1.1 christos { 788 1.1 christos struct ctx_query* q = (struct ctx_query*)arg; 789 1.1 christos 790 1.1.1.2 christos if(q->cancelled || q->w->back->want_to_quit) { 791 1.1 christos if(q->w->is_bg_thread) { 792 1.1 christos /* delete it now */ 793 1.1 christos struct ub_ctx* ctx = q->w->ctx; 794 1.1 christos lock_basic_lock(&ctx->cfglock); 795 1.1 christos (void)rbtree_delete(&ctx->queries, q->node.key); 796 1.1 christos ctx->num_async--; 797 1.1 christos context_query_delete(q); 798 1.1 christos lock_basic_unlock(&ctx->cfglock); 799 1.1 christos } 800 1.1 christos /* cancelled, do not give answer */ 801 1.1 christos return; 802 1.1 christos } 803 1.1 christos q->msg_security = s; 804 1.1.1.4 christos if(!buf) { 805 1.1 christos buf = q->w->env->scratch_buffer; 806 1.1.1.4 christos } 807 1.1 christos if(rcode != 0) { 808 1.1 christos error_encode(buf, rcode, NULL, 0, BIT_RD, NULL); 809 1.1 christos } 810 1.1.1.4 christos add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus, was_ratelimited); 811 1.1 christos } 812 1.1 christos 813 1.1 christos 814 1.1 christos /** handle new query command for bg worker */ 815 1.1 christos static void 816 1.1 christos handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) 817 1.1 christos { 818 1.1 christos uint16_t qflags, qid; 819 1.1 christos struct query_info qinfo; 820 1.1 christos struct edns_data edns; 821 1.1 christos struct ctx_query* q; 822 1.1 christos if(w->is_bg_thread) { 823 1.1 christos lock_basic_lock(&w->ctx->cfglock); 824 1.1 christos q = context_lookup_new_query(w->ctx, buf, len); 825 1.1 christos lock_basic_unlock(&w->ctx->cfglock); 826 1.1 christos } else { 827 1.1 christos q = context_deserialize_new_query(w->ctx, buf, len); 828 1.1 christos } 829 1.1 christos free(buf); 830 1.1 christos if(!q) { 831 1.1 christos log_err("failed to deserialize newq"); 832 1.1 christos return; 833 1.1 christos } 834 1.1 christos if(!setup_qinfo_edns(w, q, &qinfo, &edns)) { 835 1.1.1.4 christos add_bg_result(w, q, NULL, UB_SYNTAX, NULL, 0); 836 1.1 christos return; 837 1.1 christos } 838 1.1 christos qid = 0; 839 1.1 christos qflags = BIT_RD; 840 1.1 christos /* see if there is a fixed answer */ 841 1.1 christos sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid); 842 1.1 christos sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags); 843 1.1.1.2 christos if(local_zones_answer(w->ctx->local_zones, w->env, &qinfo, &edns, 844 1.1.1.2 christos w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0, 845 1.1.1.2 christos NULL, 0, NULL, 0, NULL)) { 846 1.1 christos regional_free_all(w->env->scratch); 847 1.1 christos q->msg_security = sec_status_insecure; 848 1.1.1.4 christos add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0); 849 1.1 christos free(qinfo.qname); 850 1.1 christos return; 851 1.1 christos } 852 1.1.1.10 christos if(w->ctx->env->auth_zones && auth_zones_downstream_answer( 853 1.1.1.10 christos w->ctx->env->auth_zones, w->env, &qinfo, &edns, NULL, 854 1.1.1.10 christos w->back->udp_buff, w->env->scratch)) { 855 1.1.1.3 christos regional_free_all(w->env->scratch); 856 1.1.1.3 christos q->msg_security = sec_status_insecure; 857 1.1.1.4 christos add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0); 858 1.1.1.3 christos free(qinfo.qname); 859 1.1.1.3 christos return; 860 1.1.1.3 christos } 861 1.1 christos q->w = w; 862 1.1 christos /* process new query */ 863 1.1 christos if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, 864 1.1.1.7 christos w->back->udp_buff, qid, libworker_bg_done_cb, q, 0)) { 865 1.1.1.4 christos add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0); 866 1.1 christos } 867 1.1 christos free(qinfo.qname); 868 1.1 christos } 869 1.1 christos 870 1.1 christos void libworker_alloc_cleanup(void* arg) 871 1.1 christos { 872 1.1 christos struct libworker* w = (struct libworker*)arg; 873 1.1 christos slabhash_clear(&w->env->rrset_cache->table); 874 1.1 christos slabhash_clear(w->env->msg_cache); 875 1.1 christos } 876 1.1 christos 877 1.1.1.2 christos struct outbound_entry* libworker_send_query(struct query_info* qinfo, 878 1.1.1.2 christos uint16_t flags, int dnssec, int want_dnssec, int nocaps, 879 1.1.1.7 christos int check_ratelimit, 880 1.1 christos struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, 881 1.1.1.7 christos size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, 882 1.1.1.7 christos struct module_qstate* q, int* was_ratelimited) 883 1.1 christos { 884 1.1 christos struct libworker* w = (struct libworker*)q->env->worker; 885 1.1 christos struct outbound_entry* e = (struct outbound_entry*)regional_alloc( 886 1.1 christos q->region, sizeof(*e)); 887 1.1 christos if(!e) 888 1.1 christos return NULL; 889 1.1 christos e->qstate = q; 890 1.1.1.2 christos e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec, 891 1.1.1.7 christos want_dnssec, nocaps, check_ratelimit, tcp_upstream, ssl_upstream, 892 1.1.1.3 christos tls_auth_name, addr, addrlen, zone, zonelen, q, 893 1.1.1.7 christos libworker_handle_service_reply, e, w->back->udp_buff, q->env, 894 1.1.1.7 christos was_ratelimited); 895 1.1 christos if(!e->qsent) { 896 1.1 christos return NULL; 897 1.1 christos } 898 1.1 christos return e; 899 1.1 christos } 900 1.1 christos 901 1.1 christos int 902 1.1 christos libworker_handle_service_reply(struct comm_point* c, void* arg, int error, 903 1.1 christos struct comm_reply* reply_info) 904 1.1 christos { 905 1.1 christos struct outbound_entry* e = (struct outbound_entry*)arg; 906 1.1 christos struct libworker* lw = (struct libworker*)e->qstate->env->worker; 907 1.1 christos 908 1.1 christos if(error != 0) { 909 1.1 christos mesh_report_reply(lw->env->mesh, e, reply_info, error); 910 1.1 christos return 0; 911 1.1 christos } 912 1.1 christos /* sanity check. */ 913 1.1 christos if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer)) 914 1.1 christos || LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) != 915 1.1 christos LDNS_PACKET_QUERY 916 1.1 christos || LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) { 917 1.1 christos /* error becomes timeout for the module as if this reply 918 1.1 christos * never arrived. */ 919 1.1 christos mesh_report_reply(lw->env->mesh, e, reply_info, 920 1.1 christos NETEVENT_TIMEOUT); 921 1.1 christos return 0; 922 1.1 christos } 923 1.1 christos mesh_report_reply(lw->env->mesh, e, reply_info, NETEVENT_NOERROR); 924 1.1 christos return 0; 925 1.1 christos } 926 1.1 christos 927 1.1 christos /* --- fake callbacks for fptr_wlist to work --- */ 928 1.1 christos void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), 929 1.1 christos uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len), 930 1.1 christos int ATTR_UNUSED(error), void* ATTR_UNUSED(arg)) 931 1.1 christos { 932 1.1 christos log_assert(0); 933 1.1 christos } 934 1.1 christos 935 1.1 christos int worker_handle_request(struct comm_point* ATTR_UNUSED(c), 936 1.1 christos void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 937 1.1 christos struct comm_reply* ATTR_UNUSED(repinfo)) 938 1.1 christos { 939 1.1 christos log_assert(0); 940 1.1 christos return 0; 941 1.1 christos } 942 1.1 christos 943 1.1 christos int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c), 944 1.1 christos void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 945 1.1 christos struct comm_reply* ATTR_UNUSED(reply_info)) 946 1.1 christos { 947 1.1 christos log_assert(0); 948 1.1 christos return 0; 949 1.1 christos } 950 1.1 christos 951 1.1 christos int remote_accept_callback(struct comm_point* ATTR_UNUSED(c), 952 1.1 christos void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 953 1.1 christos struct comm_reply* ATTR_UNUSED(repinfo)) 954 1.1 christos { 955 1.1 christos log_assert(0); 956 1.1 christos return 0; 957 1.1 christos } 958 1.1 christos 959 1.1 christos int remote_control_callback(struct comm_point* ATTR_UNUSED(c), 960 1.1 christos void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 961 1.1 christos struct comm_reply* ATTR_UNUSED(repinfo)) 962 1.1 christos { 963 1.1 christos log_assert(0); 964 1.1 christos return 0; 965 1.1 christos } 966 1.1 christos 967 1.1 christos void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg)) 968 1.1 christos { 969 1.1 christos log_assert(0); 970 1.1 christos } 971 1.1 christos 972 1.1.1.2 christos struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo), 973 1.1.1.2 christos uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), 974 1.1.1.2 christos int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), 975 1.1.1.7 christos int ATTR_UNUSED(check_ratelimit), 976 1.1.1.2 christos struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), 977 1.1.1.7 christos uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), 978 1.1.1.3 christos int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), 979 1.1.1.7 christos struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited)) 980 1.1 christos { 981 1.1 christos log_assert(0); 982 1.1 christos return 0; 983 1.1 christos } 984 1.1 christos 985 1.1 christos void 986 1.1 christos worker_alloc_cleanup(void* ATTR_UNUSED(arg)) 987 1.1 christos { 988 1.1 christos log_assert(0); 989 1.1 christos } 990 1.1 christos 991 1.1 christos void worker_stat_timer_cb(void* ATTR_UNUSED(arg)) 992 1.1 christos { 993 1.1 christos log_assert(0); 994 1.1 christos } 995 1.1 christos 996 1.1 christos void worker_probe_timer_cb(void* ATTR_UNUSED(arg)) 997 1.1 christos { 998 1.1 christos log_assert(0); 999 1.1 christos } 1000 1.1 christos 1001 1.1 christos void worker_start_accept(void* ATTR_UNUSED(arg)) 1002 1.1 christos { 1003 1.1 christos log_assert(0); 1004 1.1 christos } 1005 1.1 christos 1006 1.1 christos void worker_stop_accept(void* ATTR_UNUSED(arg)) 1007 1.1 christos { 1008 1.1 christos log_assert(0); 1009 1.1 christos } 1010 1.1 christos 1011 1.1 christos int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2)) 1012 1.1 christos { 1013 1.1 christos log_assert(0); 1014 1.1 christos return 0; 1015 1.1 christos } 1016 1.1 christos 1017 1.1 christos int 1018 1.1 christos codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) 1019 1.1 christos { 1020 1.1 christos log_assert(0); 1021 1.1 christos return 0; 1022 1.1 christos } 1023 1.1 christos 1024 1.1 christos int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) 1025 1.1 christos { 1026 1.1 christos log_assert(0); 1027 1.1 christos return 0; 1028 1.1 christos } 1029 1.1 christos 1030 1.1 christos void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg)) 1031 1.1 christos { 1032 1.1 christos log_assert(0); 1033 1.1 christos } 1034 1.1 christos 1035 1.1 christos #ifdef UB_ON_WINDOWS 1036 1.1 christos void 1037 1.1 christos worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* 1038 1.1 christos ATTR_UNUSED(arg)) { 1039 1.1 christos log_assert(0); 1040 1.1 christos } 1041 1.1 christos 1042 1.1 christos void 1043 1.1 christos wsvc_cron_cb(void* ATTR_UNUSED(arg)) 1044 1.1 christos { 1045 1.1 christos log_assert(0); 1046 1.1 christos } 1047 1.1 christos #endif /* UB_ON_WINDOWS */ 1048 1.1.1.6 christos 1049 1.1.1.6 christos #ifdef USE_DNSTAP 1050 1.1.1.6 christos void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), 1051 1.1.1.6 christos void* ATTR_UNUSED(arg)) 1052 1.1.1.6 christos { 1053 1.1.1.6 christos log_assert(0); 1054 1.1.1.6 christos } 1055 1.1.1.6 christos #endif 1056 1.1.1.6 christos 1057 1.1.1.6 christos #ifdef USE_DNSTAP 1058 1.1.1.6 christos void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), 1059 1.1.1.6 christos void* ATTR_UNUSED(arg)) 1060 1.1.1.6 christos { 1061 1.1.1.6 christos log_assert(0); 1062 1.1.1.6 christos } 1063 1.1.1.6 christos #endif 1064 1.1.1.9 christos 1065 1.1.1.9 christos void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), 1066 1.1.1.9 christos void* ATTR_UNUSED(arg)) 1067 1.1.1.9 christos { 1068 1.1.1.9 christos log_assert(0); 1069 1.1.1.9 christos } 1070 1.1.1.9 christos 1071 1.1.1.9 christos int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), 1072 1.1.1.9 christos void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 1073 1.1.1.9 christos struct comm_reply* ATTR_UNUSED(repinfo)) 1074 1.1.1.9 christos { 1075 1.1.1.9 christos log_assert(0); 1076 1.1.1.9 christos return 0; 1077 1.1.1.9 christos } 1078 1.1.1.9 christos 1079 1.1.1.9 christos #ifdef HAVE_NGTCP2 1080 1.1.1.9 christos void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), 1081 1.1.1.9 christos void* ATTR_UNUSED(arg)) 1082 1.1.1.9 christos { 1083 1.1.1.9 christos log_assert(0); 1084 1.1.1.9 christos } 1085 1.1.1.9 christos #endif 1086 1.1.1.9 christos 1087 1.1.1.9 christos #ifdef HAVE_NGTCP2 1088 1.1.1.9 christos void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), 1089 1.1.1.9 christos void* ATTR_UNUSED(arg)) 1090 1.1.1.9 christos { 1091 1.1.1.9 christos log_assert(0); 1092 1.1.1.9 christos } 1093 1.1.1.9 christos #endif 1094