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.

Reply via email to