aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/libunbound
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/libunbound')
-rw-r--r--contrib/unbound/libunbound/context.c15
-rw-r--r--contrib/unbound/libunbound/context.h6
-rw-r--r--contrib/unbound/libunbound/libunbound.c67
-rw-r--r--contrib/unbound/libunbound/libworker.c92
-rw-r--r--contrib/unbound/libunbound/unbound-event.h9
-rw-r--r--contrib/unbound/libunbound/unbound.h130
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 */