So far all libunbound based resolvers had their own cache. That's a
bit wasteful and slows things down unecessarily when we need to switch
between strategies.
This lets all of them run off of the same cache.
otto@ already pointed out that there might be situations where we
would need to drop the cache. His work on split-horizon DNS is one,
another one is when we got past a captive portal.
It's not yet clear how to handle that. Naively re-creating the cache
will not work with the current implementation, the unified_*_cache
variables would need to be refcounted. Maybe we can drop individual
RRsets from the cache or we can flush the cache.
Tests, OKs?
diff --git resolver.c resolver.c
index 7af579750a1..10acbc00053 100644
--- resolver.c
+++ resolver.c
@@ -43,14 +43,19 @@
#include <unistd.h>
#include "libunbound/config.h"
+#include "libunbound/libunbound/context.h"
#include "libunbound/libunbound/libworker.h"
#include "libunbound/libunbound/unbound.h"
#include "libunbound/libunbound/unbound-event.h"
+#include "libunbound/services/cache/rrset.h"
#include "libunbound/sldns/sbuffer.h"
#include "libunbound/sldns/rrdef.h"
#include "libunbound/sldns/pkthdr.h"
#include "libunbound/sldns/wire2str.h"
+#include "libunbound/util/config_file.h"
+#include "libunbound/util/module.h"
#include "libunbound/util/regional.h"
+#include "libunbound/util/storage/slabhash.h"
#include <openssl/crypto.h>
@@ -149,6 +154,7 @@ void new_asr_forwarders(void);
void new_static_forwarders(int);
void new_static_dot_forwarders(void);
struct uw_resolver *create_resolver(enum uw_resolver_type, int);
+void set_unified_cache(struct uw_resolver *);
void free_resolver(struct uw_resolver *);
void set_forwarders(struct uw_resolver *,
struct uw_forwarder_head *, int);
@@ -193,6 +199,10 @@ static struct trust_anchor_head trust_anchors,
new_trust_anchors;
struct event_base *ev_base;
+struct alloc_cache unified_cache_alloc;
+struct slabhash *unified_msg_cache;
+struct rrset_cache *unified_rrset_cache;
+
static const char * const as112_zones[] = {
/* RFC1918 */
"10.in-addr.arpa. transparent",
@@ -311,9 +321,10 @@ resolver_sig_handler(int sig, short event, void *arg)
void
resolver(int debug, int verbose)
{
- struct event ev_sigint, ev_sigterm;
- struct passwd *pw;
- struct timeval tv = {DECAY_PERIOD, 0};
+ struct config_file *ub_cfg;
+ struct event ev_sigint, ev_sigterm;
+ struct passwd *pw;
+ struct timeval tv = {DECAY_PERIOD, 0};
resolver_conf = config_new_empty();
@@ -367,6 +378,23 @@ resolver(int debug, int verbose)
clock_gettime(CLOCK_MONOTONIC, &last_network_change);
+ if ((ub_cfg = config_create_forlib()) == NULL)
+ fatal(NULL);
+
+ alloc_init(&unified_cache_alloc, NULL, 0);
+
+ if ((unified_msg_cache = slabhash_create(ub_cfg->msg_cache_slabs,
+ HASH_DEFAULT_STARTARRAY, ub_cfg->msg_cache_size, msgreply_sizefunc,
+ query_info_compare, query_entry_delete, reply_info_delete, NULL))
+ == NULL)
+ fatal(NULL);
+
+ if ((unified_rrset_cache = rrset_cache_adjust(NULL, ub_cfg,
+ &unified_cache_alloc)) == NULL)
+ fatal(NULL);
+
+ config_delete(ub_cfg);
+
new_recursor();
TAILQ_INIT(&autoconf_forwarder_list);
@@ -1011,6 +1039,8 @@ new_recursor(void)
return;
resolvers[UW_RES_RECURSOR] = create_resolver(UW_RES_RECURSOR, 0);
+ set_unified_cache(resolvers[UW_RES_RECURSOR]);
+
check_resolver(resolvers[UW_RES_RECURSOR]);
}
@@ -1028,6 +1058,7 @@ new_forwarders(int oppdot)
log_debug("%s: create_resolver", __func__);
resolvers[UW_RES_DHCP] = create_resolver(UW_RES_DHCP, oppdot);
+ set_unified_cache(resolvers[UW_RES_DHCP]);
check_resolver(resolvers[UW_RES_DHCP]);
}
@@ -1061,6 +1092,7 @@ new_static_forwarders(int oppdot)
log_debug("%s: create_resolver", __func__);
resolvers[UW_RES_FORWARDER] = create_resolver(UW_RES_FORWARDER, oppdot);
+ set_unified_cache(resolvers[UW_RES_FORWARDER]);
check_resolver(resolvers[UW_RES_FORWARDER]);
}
@@ -1079,10 +1111,23 @@ new_static_dot_forwarders(void)
log_debug("%s: create_resolver", __func__);
resolvers[UW_RES_DOT] = create_resolver(UW_RES_DOT, 0);
+ set_unified_cache(resolvers[UW_RES_DOT]);
check_resolver(resolvers[UW_RES_DOT]);
}
+void
+set_unified_cache(struct uw_resolver *res)
+{
+ if (res == NULL)
+ return;
+
+ res->ctx->env->msg_cache = unified_msg_cache;
+ res->ctx->env->rrset_cache = unified_rrset_cache;
+
+ context_finalize(res->ctx);
+}
+
static const struct {
const char *name;
const char *value;
@@ -1269,6 +1314,12 @@ free_resolver(struct uw_resolver *res)
res->stop = 1;
else {
evtimer_del(&res->check_ev);
+ if (res->ctx != NULL) {
+ if (res->ctx->env->msg_cache == unified_msg_cache)
+ res->ctx->env->msg_cache = NULL;
+ if (res->ctx->env->rrset_cache == unified_rrset_cache)
+ res->ctx->env->rrset_cache = NULL;
+ }
ub_ctx_delete(res->ctx);
asr_resolver_free(res->asr_ctx);
free(res->why_bogus);
--
I'm not entirely sure you are real.