On Sat, Nov 30, 2019 at 12:20:34PM +0100, Florian Obser wrote:
> 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?
rebased
diff --git resolver.c resolver.c
index 91437d9d1a0..70e690c0bf0 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);
@@ -199,6 +205,10 @@ struct event_base *ev_base;
RB_GENERATE(force_tree, force_tree_entry, entry, force_tree_cmp)
+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",
@@ -317,9 +327,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();
@@ -373,6 +384,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);
@@ -1030,6 +1058,7 @@ 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]);
}
@@ -1048,6 +1077,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]);
}
@@ -1081,6 +1111,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]);
}
@@ -1099,10 +1130,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;
@@ -1289,6 +1333,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.