diff options
Diffstat (limited to 'contrib/unbound/libunbound')
| -rw-r--r-- | contrib/unbound/libunbound/context.c | 15 | ||||
| -rw-r--r-- | contrib/unbound/libunbound/context.h | 6 | ||||
| -rw-r--r-- | contrib/unbound/libunbound/libunbound.c | 67 | ||||
| -rw-r--r-- | contrib/unbound/libunbound/libworker.c | 92 | ||||
| -rw-r--r-- | contrib/unbound/libunbound/unbound-event.h | 9 | ||||
| -rw-r--r-- | contrib/unbound/libunbound/unbound.h | 130 |
6 files changed, 221 insertions, 98 deletions
diff --git a/contrib/unbound/libunbound/context.c b/contrib/unbound/libunbound/context.c index c8d911f13c7f..a1a4adf98f0e 100644 --- a/contrib/unbound/libunbound/context.c +++ b/contrib/unbound/libunbound/context.c @@ -53,6 +53,8 @@ #include "util/storage/slabhash.h" #include "util/edns.h" #include "sldns/sbuffer.h" +#include "iterator/iter_fwd.h" +#include "iterator/iter_hints.h" int context_finalize(struct ub_ctx* ctx) @@ -70,9 +72,12 @@ context_finalize(struct ub_ctx* ctx) } else { log_init(cfg->logfile, cfg->use_syslog, NULL); } + ctx->pipe_pid = getpid(); cfg_apply_local_port_policy(cfg, 65536); config_apply(cfg); - if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) + if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env)) + return UB_INITFAIL; + if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env)) return UB_INITFAIL; listen_setup_locks(); log_edns_known_options(VERB_ALGO, ctx->env); @@ -84,6 +89,12 @@ context_finalize(struct ub_ctx* ctx) if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz, ctx->env, &ctx->mods)) return UB_INITFAIL; + if(!(ctx->env->fwds = forwards_create()) || + !forwards_apply_cfg(ctx->env->fwds, cfg)) + return UB_INITFAIL; + if(!(ctx->env->hints = hints_create()) || + !hints_apply_cfg(ctx->env->hints, cfg)) + return UB_INITFAIL; if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg)) return UB_INITFAIL; if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size, @@ -384,7 +395,7 @@ context_serialize_cancel(struct ctx_query* q, uint32_t* len) /* format of cancel: * o uint32 cmd * o uint32 async-id */ - uint8_t* p = (uint8_t*)reallocarray(NULL, sizeof(uint32_t), 2); + uint8_t* p = (uint8_t*)reallocarray(NULL, 2, sizeof(uint32_t)); if(!p) return NULL; *len = 2*sizeof(uint32_t); sldns_write_uint32(p, UB_LIBCMD_CANCEL); diff --git a/contrib/unbound/libunbound/context.h b/contrib/unbound/libunbound/context.h index c0c86fb52697..c0fc80e57be4 100644 --- a/contrib/unbound/libunbound/context.h +++ b/contrib/unbound/libunbound/context.h @@ -89,6 +89,12 @@ struct ub_ctx { pid_t bg_pid; /** tid of bg worker thread */ ub_thread_type bg_tid; + /** pid when pipes are created. This was the process when the + * setup was called. Helps with clean up, so we can tell after a fork + * which side of the fork the delete is on. */ + pid_t pipe_pid; + /** when threaded, the worker that exists in the created thread. */ + struct libworker* thread_worker; /** do threading (instead of forking) for async resolution */ int dothread; diff --git a/contrib/unbound/libunbound/libunbound.c b/contrib/unbound/libunbound/libunbound.c index 038b7b927a74..9c6a3e309717 100644 --- a/contrib/unbound/libunbound/libunbound.c +++ b/contrib/unbound/libunbound/libunbound.c @@ -66,6 +66,8 @@ #include "services/authzone.h" #include "services/listen_dnsport.h" #include "sldns/sbuffer.h" +#include "iterator/iter_fwd.h" +#include "iterator/iter_hints.h" #ifdef HAVE_PTHREAD #include <signal.h> #endif @@ -171,6 +173,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) ctx->env->worker = NULL; ctx->env->need_to_validate = 0; modstack_init(&ctx->mods); + ctx->env->modstack = &ctx->mods; rbtree_init(&ctx->queries, &context_query_cmp); return ctx; } @@ -185,7 +188,9 @@ ub_ctx_create(void) int e = errno; ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); - modstack_desetup(&ctx->mods, ctx->env); + modstack_call_deinit(&ctx->mods, ctx->env); + modstack_call_destartup(&ctx->mods, ctx->env); + modstack_free(&ctx->mods); listen_desetup_locks(); edns_known_options_delete(ctx->env); edns_strings_delete(ctx->env->edns_strings); @@ -199,7 +204,9 @@ ub_ctx_create(void) tube_delete(ctx->qq_pipe); ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); - modstack_desetup(&ctx->mods, ctx->env); + modstack_call_deinit(&ctx->mods, ctx->env); + modstack_call_destartup(&ctx->mods, ctx->env); + modstack_free(&ctx->mods); listen_desetup_locks(); edns_known_options_delete(ctx->env); edns_strings_delete(ctx->env->edns_strings); @@ -305,11 +312,31 @@ ub_ctx_delete(struct ub_ctx* ctx) int do_stop = 1; if(!ctx) return; + /* if the delete is called but it has forked, and before the fork + * the context was finalized, then the bg worker is not stopped + * from here. There is one worker, but two contexts that refer to + * it and only one should clean up, the one with getpid == pipe_pid.*/ + if(ctx->created_bg && ctx->pipe_pid != getpid()) { + do_stop = 0; +#ifndef USE_WINSOCK + /* Stop events from getting deregistered, if the backend is + * epoll, the epoll fd is the same as the other process. + * That process should deregister them. */ + if(ctx->qq_pipe->listen_com) + ctx->qq_pipe->listen_com->event_added = 0; + if(ctx->qq_pipe->res_com) + ctx->qq_pipe->res_com->event_added = 0; + if(ctx->rr_pipe->listen_com) + ctx->rr_pipe->listen_com->event_added = 0; + if(ctx->rr_pipe->res_com) + ctx->rr_pipe->res_com->event_added = 0; +#endif + } /* see if bg thread is created and if threads have been killed */ /* no locks, because those may be held by terminated threads */ /* for processes the read pipe is closed and we see that on read */ #ifdef HAVE_PTHREAD - if(ctx->created_bg && ctx->dothread) { + if(ctx->created_bg && ctx->dothread && do_stop) { if(pthread_kill(ctx->bg_tid, 0) == ESRCH) { /* thread has been killed */ do_stop = 0; @@ -318,9 +345,28 @@ ub_ctx_delete(struct ub_ctx* ctx) #endif /* HAVE_PTHREAD */ if(do_stop) ub_stop_bg(ctx); + if(ctx->created_bg && ctx->pipe_pid != getpid() && ctx->thread_worker) { + /* This delete is happening from a different process. Delete + * the thread worker from this process memory space. The + * thread is not there to do so, so it is freed here. */ + struct ub_event_base* evbase = comm_base_internal( + ctx->thread_worker->base); + libworker_delete_event(ctx->thread_worker); + ctx->thread_worker = NULL; +#ifdef USE_MINI_EVENT + ub_event_base_free(evbase); +#else + /* cannot event_base_free, because the epoll_fd cleanup + * in libevent could stop the original event_base in the + * other process from working. */ + free(evbase); +#endif + } libworker_delete_event(ctx->event_worker); - modstack_desetup(&ctx->mods, ctx->env); + modstack_call_deinit(&ctx->mods, ctx->env); + modstack_call_destartup(&ctx->mods, ctx->env); + modstack_free(&ctx->mods); a = ctx->alloc_list; while(a) { na = a->super; @@ -342,6 +388,8 @@ ub_ctx_delete(struct ub_ctx* ctx) config_delete(ctx->env->cfg); edns_known_options_delete(ctx->env); edns_strings_delete(ctx->env->edns_strings); + forwards_delete(ctx->env->fwds); + hints_delete(ctx->env->hints); auth_zones_delete(ctx->env->auth_zones); free(ctx->env); } @@ -939,7 +987,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) if(!addr) { /* disable fwd mode - the root stub should be first. */ if(ctx->env->cfg->forwards && - strcmp(ctx->env->cfg->forwards->name, ".") == 0) { + (ctx->env->cfg->forwards->name && + strcmp(ctx->env->cfg->forwards->name, ".") == 0)) { s = ctx->env->cfg->forwards; ctx->env->cfg->forwards = s->next; s->next = NULL; @@ -951,7 +1000,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) lock_basic_unlock(&ctx->cfglock); /* check syntax for addr */ - if(!extstrtoaddr(addr, &storage, &stlen)) { + if(!extstrtoaddr(addr, &storage, &stlen, UNBOUND_DNS_PORT)) { errno=EINVAL; return UB_SYNTAX; } @@ -959,7 +1008,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) /* it parses, add root stub in front of list */ lock_basic_lock(&ctx->cfglock); if(!ctx->env->cfg->forwards || - strcmp(ctx->env->cfg->forwards->name, ".") != 0) { + (ctx->env->cfg->forwards->name && + strcmp(ctx->env->cfg->forwards->name, ".") != 0)) { s = calloc(1, sizeof(*s)); if(!s) { lock_basic_unlock(&ctx->cfglock); @@ -977,6 +1027,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) ctx->env->cfg->forwards = s; } else { log_assert(ctx->env->cfg->forwards); + log_assert(ctx->env->cfg->forwards->name); s = ctx->env->cfg->forwards; } dupl = strdup(addr); @@ -1031,7 +1082,7 @@ int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr, if(addr) { struct sockaddr_storage storage; socklen_t stlen; - if(!extstrtoaddr(addr, &storage, &stlen)) { + if(!extstrtoaddr(addr, &storage, &stlen, UNBOUND_DNS_PORT)) { errno=EINVAL; return UB_SYNTAX; } diff --git a/contrib/unbound/libunbound/libworker.c b/contrib/unbound/libunbound/libworker.c index ab28dd54f942..6e7244c03fee 100644 --- a/contrib/unbound/libunbound/libworker.c +++ b/contrib/unbound/libunbound/libworker.c @@ -62,6 +62,7 @@ #include "util/random.h" #include "util/config_file.h" #include "util/netevent.h" +#include "util/proxy_protocol.h" #include "util/storage/lookup3.h" #include "util/storage/slabhash.h" #include "util/net_help.h" @@ -69,8 +70,6 @@ #include "util/data/msgreply.h" #include "util/data/msgencode.h" #include "util/tube.h" -#include "iterator/iter_fwd.h" -#include "iterator/iter_hints.h" #include "sldns/sbuffer.h" #include "sldns/str2wire.h" #ifdef USE_DNSTAP @@ -99,8 +98,6 @@ libworker_delete_env(struct libworker* w) !w->is_bg || w->is_bg_thread); sldns_buffer_free(w->env->scratch_buffer); regional_destroy(w->env->scratch); - forwards_delete(w->env->fwds); - hints_delete(w->env->hints); ub_randfree(w->env->rnd); free(w->env); } @@ -158,30 +155,19 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) } w->env->scratch = regional_create_custom(cfg->msg_buffer_size); w->env->scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size); - w->env->fwds = forwards_create(); - if(w->env->fwds && !forwards_apply_cfg(w->env->fwds, cfg)) { - forwards_delete(w->env->fwds); - w->env->fwds = NULL; - } - w->env->hints = hints_create(); - if(w->env->hints && !hints_apply_cfg(w->env->hints, cfg)) { - hints_delete(w->env->hints); - w->env->hints = NULL; - } - if(cfg->ssl_upstream || (cfg->tls_cert_bundle && cfg->tls_cert_bundle[0]) || cfg->tls_win_cert) { - w->sslctx = connect_sslctx_create(NULL, NULL, - cfg->tls_cert_bundle, cfg->tls_win_cert); - if(!w->sslctx) { - /* to make the setup fail after unlock */ - hints_delete(w->env->hints); - w->env->hints = NULL; - } +#ifdef HAVE_SSL + w->sslctx = connect_sslctx_create(NULL, NULL, + cfg->tls_cert_bundle, cfg->tls_win_cert); + if(!w->sslctx) { + /* to make the setup fail after unlock */ + sldns_buffer_free(w->env->scratch_buffer); + w->env->scratch_buffer = NULL; } +#endif if(!w->is_bg || w->is_bg_thread) { lock_basic_unlock(&ctx->cfglock); } - if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds || - !w->env->hints) { + if(!w->env->scratch || !w->env->scratch_buffer) { libworker_delete(w); return NULL; } @@ -265,6 +251,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) w->env->kill_sub = &mesh_state_delete; w->env->detect_cycle = &mesh_detect_cycle; comm_base_timept(w->base, &w->env->now, &w->env->now_tv); + pp_init(&sldns_write_uint16, &sldns_write_uint32); return w; } @@ -305,6 +292,7 @@ libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len) log_err("unknown command for bg worker %d", (int)context_serial_getcmd(msg, len)); /* and fall through to quit */ + ATTR_FALLTHROUGH /* fallthrough */ case UB_LIBCMD_QUIT: free(msg); @@ -395,6 +383,7 @@ int libworker_bg(struct ub_ctx* ctx) w = libworker_setup(ctx, 1, NULL); if(!w) return UB_NOMEM; w->is_bg_thread = 1; + ctx->thread_worker = w; #ifdef ENABLE_LOCK_CHECKS w->thread_num = 1; /* for nicer DEBUG checklocks */ #endif @@ -434,7 +423,7 @@ int libworker_bg(struct ub_ctx* ctx) static int fill_canon(struct ub_result* res, uint8_t* s) { - char buf[255+2]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(s, buf); res->canonname = strdup(buf); return res->canonname != 0; @@ -604,6 +593,8 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q, edns->opt_list_out = NULL; edns->opt_list_inplace_cb_out = NULL; edns->padding_block_size = 0; + edns->cookie_present = 0; + edns->cookie_valid = 0; if(sldns_buffer_capacity(w->back->udp_buff) < 65535) edns->udp_size = (uint16_t)sldns_buffer_capacity( w->back->udp_buff); @@ -639,8 +630,9 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) free(qinfo.qname); return UB_NOERROR; } - if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones, - w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { + if(ctx->env->auth_zones && auth_zones_downstream_answer( + ctx->env->auth_zones, w->env, &qinfo, &edns, NULL, + w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); libworker_fillup_fg(q, LDNS_RCODE_NOERROR, w->back->udp_buff, sec_status_insecure, NULL, 0); @@ -650,7 +642,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) } /* process new query */ if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, - w->back->udp_buff, qid, libworker_fg_done_cb, q)) { + w->back->udp_buff, qid, libworker_fg_done_cb, q, 0)) { free(qinfo.qname); return UB_NOMEM; } @@ -718,8 +710,9 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, w->back->udp_buff, sec_status_insecure, NULL, 0); return UB_NOERROR; } - if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones, - w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { + if(ctx->env->auth_zones && auth_zones_downstream_answer( + ctx->env->auth_zones, w->env, &qinfo, &edns, NULL, + w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); free(qinfo.qname); libworker_event_done_cb(q, LDNS_RCODE_NOERROR, @@ -730,7 +723,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, if(async_id) *async_id = q->querynum; if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, - w->back->udp_buff, qid, libworker_event_done_cb, q)) { + w->back->udp_buff, qid, libworker_event_done_cb, q, 0)) { free(qinfo.qname); return UB_NOMEM; } @@ -856,8 +849,9 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) free(qinfo.qname); return; } - if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones, - w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { + if(w->ctx->env->auth_zones && auth_zones_downstream_answer( + w->ctx->env->auth_zones, w->env, &qinfo, &edns, NULL, + w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); q->msg_security = sec_status_insecure; add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0); @@ -867,7 +861,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) q->w = w; /* process new query */ if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, - w->back->udp_buff, qid, libworker_bg_done_cb, q)) { + w->back->udp_buff, qid, libworker_bg_done_cb, q, 0)) { add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0); } free(qinfo.qname); @@ -1067,3 +1061,33 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), log_assert(0); } #endif + +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + +#ifdef HAVE_NGTCP2 +void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif + +#ifdef HAVE_NGTCP2 +void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} +#endif diff --git a/contrib/unbound/libunbound/unbound-event.h b/contrib/unbound/libunbound/unbound-event.h index a5d5c038b68f..5ca81908a904 100644 --- a/contrib/unbound/libunbound/unbound-event.h +++ b/contrib/unbound/libunbound/unbound-event.h @@ -52,8 +52,8 @@ * unbound was compiled with, otherwise it wouldn't work, the event and * event_base structures would be different. */ -#ifndef _UB_UNBOUND_EVENT_H -#define _UB_UNBOUND_EVENT_H +#ifndef UB_UNBOUND_EVENT_H +#define UB_UNBOUND_EVENT_H #ifdef __cplusplus extern "C" { @@ -230,7 +230,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base); * @param callback: this is called on completion of the resolution. * It is called as: * void callback(void* mydata, int rcode, void* packet, int packet_len, - * int sec, char* why_bogus) + * int sec, char* why_bogus, int was_ratelimited) * with mydata: the same as passed here, you may pass NULL, * with rcode: 0 on no error, nonzero for mostly SERVFAIL situations, * this is a DNS rcode. @@ -241,6 +241,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base); * with packet_len: length in bytes of the packet buffer. * with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure. * with why_bogus: text string explaining why it is bogus (or NULL). + * with was_ratelimited: if the query was ratelimited. * These point to buffers inside unbound; do not deallocate the packet or * error string. * @@ -261,4 +262,4 @@ int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype, } #endif -#endif /* _UB_UNBOUND_H */ +#endif /* UB_UNBOUND_EVENT_H */ diff --git a/contrib/unbound/libunbound/unbound.h b/contrib/unbound/libunbound/unbound.h index ee8558759065..c274f80ab897 100644 --- a/contrib/unbound/libunbound/unbound.h +++ b/contrib/unbound/libunbound/unbound.h @@ -4,22 +4,22 @@ * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -36,7 +36,7 @@ /** * \file * - * This file contains functions to resolve DNS queries and + * This file contains functions to resolve DNS queries and * validate the answers. Synchronously and asynchronously. * * Several ways to use this interface from an application wishing @@ -65,7 +65,7 @@ * ... or process() calls my_callback() with results. * * ... if the application has nothing more to do, wait for answer - * ub_wait(ctx); + * ub_wait(ctx); * * Application threaded. Blocking. * Blocking, same as above. The current thread does the work. @@ -83,7 +83,7 @@ * CRYPTO_set_id_callback and CRYPTO_set_locking_callback. * * If no threading is compiled in, the above async example uses fork(2) to - * create a process to perform the work. The forked process exits when the + * create a process to perform the work. The forked process exits when the * calling process exits, or ctx_delete() is called. * Otherwise, for asynchronous with threading, a worker thread is created. * @@ -94,8 +94,8 @@ * The second calls another worker thread (or process) to perform the work. * And no buffers need to be set up, but a context-switch happens. */ -#ifndef _UB_UNBOUND_H -#define _UB_UNBOUND_H +#ifndef UB_UNBOUND_H +#define UB_UNBOUND_H #ifdef __cplusplus extern "C" { @@ -128,10 +128,10 @@ struct ub_result { /** the class asked for */ int qclass; - /** - * a list of network order DNS rdata items, terminated with a + /** + * a list of network order DNS rdata items, terminated with a * NULL pointer, so that data[0] is the first result entry, - * data[1] the second, and the last entry is NULL. + * data[1] the second, and the last entry is NULL. * If there was no data, data[0] is NULL. */ char** data; @@ -139,8 +139,8 @@ struct ub_result { /** the length in bytes of the data items, len[i] for data[i] */ int* len; - /** - * canonical name for the result (the final cname). + /** + * canonical name for the result (the final cname). * zero terminated string. * May be NULL if no canonical name exists. */ @@ -165,9 +165,9 @@ struct ub_result { */ int havedata; - /** + /** * If there was no data, and the domain did not exist, this is true. - * If it is false, and there was no data, then the domain name + * If it is false, and there was no data, then the domain name * is purported to exist, but the requested data type is not available. */ int nxdomain; @@ -182,19 +182,19 @@ struct ub_result { */ int secure; - /** - * If the result was not secure (secure==0), and this result is due + /** + * If the result was not secure (secure==0), and this result is due * to a security failure, bogus is true. * This means the data has been actively tampered with, signatures - * failed, expected signatures were not present, timestamps on + * failed, expected signatures were not present, timestamps on * signatures were out of date and so on. * - * If !secure and !bogus, this can happen if the data is not secure - * because security is disabled for that domain name. + * If !secure and !bogus, this can happen if the data is not secure + * because security is disabled for that domain name. * This means the data is from a domain where data is not signed. */ int bogus; - + /** * If the result is bogus this contains a string (zero terminated) * that describes the failure. There may be other errors as well @@ -222,7 +222,7 @@ struct ub_result { * The readable function definition looks like: * void my_callback(void* my_arg, int err, struct ub_result* result); * It is called with - * void* my_arg: your pointer to a (struct of) data of your choice, + * void* my_arg: your pointer to a (struct of) data of your choice, * or NULL. * int err: if 0 all is OK, otherwise an error occurred and no results * are forthcoming. @@ -301,8 +301,8 @@ int ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val); * This is a power-users interface that lets you specify all sorts * of options. * @param str: the string is malloced and returned here. NULL on error. - * The caller must free() the string. In cases with multiple - * entries (auto-trust-anchor-file), a newline delimited list is + * The caller must free() the string. In cases with multiple + * entries (auto-trust-anchor-file), a newline delimited list is * returned in the string. * @return 0 if OK else an error code (malloc failure, syntax error). */ @@ -321,10 +321,10 @@ int ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str); int ub_ctx_config(struct ub_ctx* ctx, const char* fname); /** - * Set machine to forward DNS queries to, the caching resolver to use. - * IP4 or IP6 address. Forwards all DNS requests to that machine, which - * is expected to run a recursive resolver. If the proxy is not - * DNSSEC-capable, validation may fail. Can be called several times, in + * Set machine to forward DNS queries to, the caching resolver to use. + * IP4 or IP6 address. Forwards all DNS requests to that machine, which + * is expected to run a recursive resolver. If the proxy is not + * DNSSEC-capable, validation may fail. Can be called several times, in * that case the addresses are used as backup servers. * * To read the list of nameservers from /etc/resolv.conf (from DHCP or so), @@ -389,7 +389,7 @@ int ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname); /** * Read list of hosts from the filename given. - * Usually "/etc/hosts". + * Usually "/etc/hosts". * These addresses are not flagged as DNSSEC secure when queried for. * * @param ctx: context. @@ -403,7 +403,7 @@ int ub_ctx_hosts(struct ub_ctx* ctx, const char* fname); /** * Add a trust anchor to the given context. * The trust anchor is a string, on one line, that holds a valid DNSKEY or - * DS RR. + * DS RR. * @param ctx: context. * At this time it is only possible to add trusted keys before the * first resolve is done. @@ -465,7 +465,7 @@ int ub_ctx_debugout(struct ub_ctx* ctx, void* out); * Set debug verbosity for the context * Output is directed to stderr. * @param ctx: context. - * @param d: debug level, 0 is off, 1 is very minimal, 2 is detailed, + * @param d: debug level, 0 is off, 1 is very minimal, 2 is detailed, * and 3 is lots. * @return 0 if OK, else error. */ @@ -474,10 +474,10 @@ int ub_ctx_debuglevel(struct ub_ctx* ctx, int d); /** * Set a context behaviour for asynchronous action. * @param ctx: context. - * @param dothread: if true, enables threading and a call to resolve_async() + * @param dothread: if true, enables threading and a call to resolve_async() * creates a thread to handle work in the background. * If false, a process is forked to handle work in the background. - * Changes to this setting after async() calls have been made have + * Changes to this setting after async() calls have been made have * no effect (delete and re-create the context to change). * @return 0 if OK, else error. */ @@ -495,7 +495,7 @@ int ub_poll(struct ub_ctx* ctx); /** * Wait for a context to finish with results. Calls ub_process() after - * the wait for you. After the wait, there are no more outstanding + * the wait for you. After the wait, there are no more outstanding * asynchronous queries. * @param ctx: context. * @return: 0 if OK, else error. @@ -530,11 +530,11 @@ int ub_process(struct ub_ctx* ctx); * @param rrtype: type of RR in host order, 1 is A (address). * @param rrclass: class of RR in host order, 1 is IN (for internet). * @param result: the result data is returned in a newly allocated result - * structure. May be NULL on return, return value is set to an error + * structure. May be NULL on return, return value is set to an error * in that case (out of memory). * @return 0 if OK, else error. */ -int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, +int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass, struct ub_result** result); /** @@ -561,11 +561,11 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, * If an error happens during processing, your callback will be called * with error set to a nonzero value (and result==NULL). * @param async_id: if you pass a non-NULL value, an identifier number is - * returned for the query as it is in progress. It can be used to + * returned for the query as it is in progress. It can be used to * cancel the query. * @return 0 if OK, else error. */ -int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype, +int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass, void* mydata, ub_callback_type callback, int* async_id); /** @@ -589,7 +589,7 @@ int ub_cancel(struct ub_ctx* ctx, int async_id); */ void ub_resolve_free(struct ub_result* result); -/** +/** * Convert error value to a human readable string. * @param err: error code from one of the libunbound functions. * The error codes are from the type enum ub_ctx_err. @@ -605,7 +605,7 @@ const char* ub_strerror(int err); int ub_ctx_print_local_zones(struct ub_ctx* ctx); /** - * Add a new zone with the zonetype to the local authority info of the + * Add a new zone with the zonetype to the local authority info of the * library. * @param ctx: context. Is finalized by the routine. * @param zone_name: name of the zone in text, "example.com" @@ -613,7 +613,7 @@ int ub_ctx_print_local_zones(struct ub_ctx* ctx); * @param zone_type: type of the zone (like for unbound.conf) in text. * @return 0 if OK, else error. */ -int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, +int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, const char *zone_type); /** @@ -649,7 +649,7 @@ int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data); */ const char* ub_version(void); -/** +/** * Some global statistics that are not in struct stats_info, * this struct is shared on a shm segment (shm-key in unbound.conf) */ @@ -695,13 +695,22 @@ struct ub_server_stats { long long num_queries; /** number of queries that have been dropped/ratelimited by ip. */ long long num_queries_ip_ratelimited; + /** number of queries with a valid DNS Cookie. */ + long long num_queries_cookie_valid; + /** number of queries with only the client part of the DNS Cookie. */ + long long num_queries_cookie_client; + /** number of queries with invalid DNS Cookie. */ + long long num_queries_cookie_invalid; /** number of queries that had a cache-miss. */ long long num_queries_missed_cache; /** number of prefetch queries - cachehits with prefetch */ long long num_queries_prefetch; - + /** number of queries which are too late to process */ + long long num_queries_timed_out; + /** the longest wait time in the queue */ + long long max_query_time_us; /** - * Sum of the querylistsize of the worker for + * Sum of the querylistsize of the worker for * every query that missed cache. To calculate average. */ long long sum_query_list_size; @@ -725,6 +734,8 @@ struct ub_server_stats { long long qtcp; /** number of outgoing queries over TCP */ long long qtcp_outgoing; + /** number of outgoing queries over UDP */ + long long qudp_outgoing; /** number of queries over (DNS over) TLS */ long long qtls; /** number of queries over (DNS over) HTTPS */ @@ -761,6 +772,8 @@ struct ub_server_stats { long long ans_bogus; /** rrsets marked bogus by validator */ long long rrset_bogus; + /** number of signature validation operations performed by validator */ + long long val_ops; /** number of queries that have been ratelimited by domain recursion. */ long long queries_ratelimited; /** unwanted traffic received on server-facing ports */ @@ -771,12 +784,12 @@ struct ub_server_stats { long long tcp_accept_usage; /** expired answers served from cache */ long long ans_expired; - /** histogram data exported to array + /** histogram data exported to array * if the array is the same size, no data is lost, and * if all histograms are same size (is so by default) then * adding up works well. */ long long hist[UB_STATS_BUCKET_NUM]; - + /** number of message cache entries */ long long msg_cache_count; /** number of rrset cache entries */ @@ -786,6 +799,11 @@ struct ub_server_stats { /** number of key cache entries */ long long key_cache_count; + /** maximum number of collisions in the msg cache */ + long long msg_cache_max_collisions; + /** maximum number of collisions in the rrset cache */ + long long rrset_cache_max_collisions; + /** number of queries that used dnscrypt */ long long num_query_dnscrypt_crypted; /** number of queries that queried dnscrypt certificates */ @@ -817,6 +835,8 @@ struct ub_server_stats { /** number of queries answered from edns-subnet specific data, and * the answer was from the edns-subnet cache. */ long long num_query_subnet_cache; + /** number of queries served from cachedb */ + long long num_query_cachedb; /** number of bytes in the stream wait buffers */ long long mem_stream_wait; /** number of bytes in the HTTP2 query buffers */ @@ -827,9 +847,19 @@ struct ub_server_stats { long long qtls_resume; /** RPZ action stats */ long long rpz_action[UB_STATS_RPZ_ACTION_NUM]; + /** number of bytes in QUIC buffers */ + long long mem_quic; + /** number of queries over (DNS over) QUIC */ + long long qquic; + /** number of queries removed due to discard-timeout */ + long long num_queries_discard_timeout; + /** number of queries removed due to wait-limit */ + long long num_queries_wait_limit; + /** number of dns error reports generated */ + long long num_dns_error_reports; }; -/** +/** * Statistics to send over the control pipe when asked * This struct is made to be memcopied, sent in binary. * shm mapped with (number+1) at num_threads+1, with first as total @@ -858,4 +888,4 @@ struct ub_stats_info { } #endif -#endif /* _UB_UNBOUND_H */ +#endif /* UB_UNBOUND_H */ |
