]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Introduce num.query.cachedb to track cache hits for the external cache.
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Tue, 30 May 2023 15:49:50 +0000 (17:49 +0200)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Tue, 30 May 2023 15:49:50 +0000 (17:49 +0200)
13 files changed:
cachedb/cachedb.c
daemon/remote.c
daemon/stats.c
doc/unbound-control.8.in
libunbound/unbound.h
services/mesh.c
services/mesh.h
smallapp/unbound-control.c
testdata/stat_values.tdir/stat_values.pre
testdata/stat_values.tdir/stat_values.test
testdata/stat_values.tdir/stat_values.testns
testdata/stat_values.tdir/stat_values_cachedb.conf [new file with mode: 0644]
util/module.h

index 245daa9869674943b939aac06c29639a0cf903b6..36995d6c569a65b14108672b673ec3f60f788ff7 100644 (file)
@@ -228,7 +228,7 @@ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
        return 1;
 }
 
-int 
+int
 cachedb_init(struct module_env* env, int id)
 {
        struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1,
@@ -267,19 +267,16 @@ cachedb_init(struct module_env* env, int id)
        return 1;
 }
 
-void 
+void
 cachedb_deinit(struct module_env* env, int id)
 {
        struct cachedb_env* cachedb_env;
        if(!env || !env->modinfo[id])
                return;
        cachedb_env = (struct cachedb_env*)env->modinfo[id];
-       /* free contents */
-       /* TODO */
        if(cachedb_env->enabled) {
                (*cachedb_env->backend->deinit)(env, cachedb_env);
        }
-
        free(cachedb_env);
        env->modinfo[id] = NULL;
 }
@@ -693,6 +690,7 @@ cachedb_handle_query(struct module_qstate* qstate,
        struct cachedb_qstate* ATTR_UNUSED(iq),
        struct cachedb_env* ie, int id)
 {
+       qstate->is_cachedb_answer = 0;
        /* check if we are enabled, and skip if so */
        if(!ie->enabled) {
                /* pass request to next module */
@@ -746,6 +744,7 @@ cachedb_handle_query(struct module_qstate* qstate,
                                qstate->ext_state[id] = module_wait_module;
                                return;
                }
+               qstate->is_cachedb_answer = 1;
                /* we are done with the query */
                qstate->ext_state[id] = module_finished;
                return;
@@ -768,6 +767,7 @@ static void
 cachedb_handle_response(struct module_qstate* qstate,
        struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
 {
+       qstate->is_cachedb_answer = 0;
        /* check if we are not enabled or instructed to not cache, and skip */
        if(!ie->enabled || qstate->no_cache_store) {
                /* we are done with the query */
index 03daa935ee1809cf7f34cb972ab0a42bb64feda5..d89ecd16549d59d926e48eff6b760531e79de6c6 100644 (file)
@@ -1064,6 +1064,10 @@ print_ext(RES* ssl, struct ub_stats_info* s, int inhibit_zero)
        if(!ssl_printf(ssl, "num.query.subnet_cache"SQ"%lu\n",
                (unsigned long)s->svr.num_query_subnet_cache)) return 0;
 #endif /* CLIENT_SUBNET */
+#ifdef USE_CACHEDB
+       if(!ssl_printf(ssl, "num.query.cachedb"SQ"%lu\n",
+               (unsigned long)s->svr.num_query_cachedb)) return 0;
+#endif /* USE_CACHEDB */
        return 1;
 }
 
index cef7de8272109631f9c0c1bbbab92efa6a060f77..405d8589ee867cfe3ad0605b671084e2ac40b809 100644 (file)
@@ -356,6 +356,11 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
        s->svr.num_query_subnet = 0;
        s->svr.num_query_subnet_cache = 0;
 #endif
+#ifdef USE_CACHEDB
+       s->svr.num_query_cachedb += (long long)worker->env.mesh->ans_cachedb;
+#else
+       s->svr.num_query_cachedb = 0;
+#endif
 
        /* get tcp accept usage */
        s->svr.tcp_accept_usage = 0;
@@ -476,6 +481,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
                total->svr.unwanted_replies += a->svr.unwanted_replies;
                total->svr.unwanted_queries += a->svr.unwanted_queries;
                total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
+#ifdef USE_CACHEDB
+               total->svr.num_query_cachedb += a->svr.num_query_cachedb;
+#endif
                for(i=0; i<UB_STATS_QTYPE_NUM; i++)
                        total->svr.qtype[i] += a->svr.qtype[i];
                for(i=0; i<UB_STATS_QCLASS_NUM; i++)
index 8ab2214563252e5521ff79e263de0ae33cf70fef..acbc89abe054fbb90b2a1b43fa12771f52b3b3f6 100644 (file)
@@ -718,7 +718,12 @@ Number of queries that got an answer that contained EDNS client subnet data.
 .I num.query.subnet_cache
 Number of queries answered from the edns client subnet cache.  These are
 counted as cachemiss by the main counters, but hit the client subnet
-specific cache, after getting processed by the edns client subnet module.
+specific cache after getting processed by the edns client subnet module.
+.TP
+.I num.query.cachedb
+Number of queries answered from the external cache of cachedb.
+These are counted as cachemiss by the main counters, but hit the cachedb
+external cache after getting processed by the cachedb module.
 .TP
 .I num.rpz.action.<rpz_action>
 Number of queries answered using configured RPZ policy, per RPZ action type.
index 8a97b16feaee1a06c1c6ba9eb905f0669aae84e2..97be66a88f2b77a8d679bd6b2de6be83dbf19865 100644 (file)
@@ -827,6 +827,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 */
index bff0c03e6f043027149d36173ca7539f86268dac..22defd58032124de6ae3bb2b9836978df3238582 100644 (file)
@@ -206,6 +206,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
        mesh->stats_jostled = 0;
        mesh->stats_dropped = 0;
        mesh->ans_expired = 0;
+       mesh->ans_cachedb = 0;
        mesh->max_reply_states = env->cfg->num_queries_per_thread;
        mesh->max_forever_states = (mesh->max_reply_states+1)/2;
 #ifndef S_SPLINT_S
@@ -1492,6 +1493,12 @@ void mesh_query_done(struct mesh_state* mstate)
                        }
                        prev = r;
                        prev_buffer = r_buffer;
+
+                       /* Account for each reply sent. */
+                       if(mstate->s.env->cfg->stat_extended
+                               && mstate->s.is_cachedb_answer) {
+                               mstate->s.env->mesh->ans_cachedb++;
+                       }
                }
        }
        if(mstate->reply_list) {
@@ -1518,6 +1525,11 @@ void mesh_query_done(struct mesh_state* mstate)
                if(!mstate->reply_list && !mstate->cb_list &&
                        mstate->super_set.count == 0)
                        mstate->s.env->mesh->num_detached_states++;
+               /* Account for each callback. */
+               if(mstate->s.env->cfg->stat_extended
+                       && mstate->s.is_cachedb_answer) {
+                       mstate->s.env->mesh->ans_cachedb++;
+               }
                mesh_do_callback(mstate, mstate->s.return_rcode, rep, c, &tv);
        }
 }
@@ -1889,6 +1901,7 @@ mesh_stats_clear(struct mesh_area* mesh)
        mesh->ans_secure = 0;
        mesh->ans_bogus = 0;
        mesh->ans_expired = 0;
+       mesh->ans_cachedb = 0;
        memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
        memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
        mesh->ans_nodata = 0;
@@ -2161,6 +2174,8 @@ mesh_serve_expired_callback(void* arg)
                if(!mstate->reply_list && !mstate->cb_list &&
                        mstate->super_set.count == 0)
                        qstate->env->mesh->num_detached_states++;
+               /* Account for each callback. */
+               mesh->ans_expired++;
                mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c, &tv);
        }
 }
index 25121a67b3a5595ecfe762a19cf4727bd18f9e33..b83a3df5c58fa81f09423575bbcf42675fdb972c 100644 (file)
@@ -114,6 +114,8 @@ struct mesh_area {
        size_t stats_dropped;
        /** stats, number of expired replies sent */
        size_t ans_expired;
+       /** stats, number of cached replies from cachedb */
+       size_t ans_cachedb;
        /** number of replies sent */
        size_t replies_sent;
        /** sum of waiting times for the replies */
index bbc09659fb049dc7b6cf5afba33cef338e3bb608..891ce23ac0fd556c2484845590afedb50221efda 100644 (file)
@@ -407,6 +407,9 @@ static void print_extended(struct ub_stats_info* s, int inhibit_zero)
        PR_UL("num.query.subnet", s->svr.num_query_subnet);
        PR_UL("num.query.subnet_cache", s->svr.num_query_subnet_cache);
 #endif
+#ifdef USE_CACHEDB
+       PR_UL("num.query.cachedb", s->svr.num_query_cachedb);
+#endif
 }
 
 /** print statistics out of memory structures */
index 2db4a17e009650a5d0afa006af928608e88a5337..ad1166a06362d701304a6da34a68b970c6375933 100644 (file)
@@ -5,6 +5,13 @@
 [ -f .tpkg.var.test ] && source .tpkg.var.test
 
 . ../common.sh
+
+PRE="../.."
+if grep "define USE_CACHEDB 1" $PRE/config.h; then
+    USE_CACHEDB=1
+    echo "USE_CACHEDB=1" >> .tpkg.var.test
+fi
+
 get_random_port 4
 UNBOUND_PORT=$RND_PORT
 FWD_PORT=$(($RND_PORT + 1))
@@ -29,8 +36,8 @@ echo "FWD_EXPIRED_PID=$FWD_EXPIRED_PID" >> .tpkg.var.test
 
 # make config file
 sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values.conf > ub.conf
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_cachedb.conf > ub_cachedb.conf
 # start unbound in the background
-PRE="../.."
 $PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
 UNBOUND_PID=$!
 echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
index ef86a0471d60673ce4e21a1fd956a8b2d7bb2a98..60b6252794ac1cdbd31f64c8fb6d271081b0cad1 100644 (file)
@@ -50,7 +50,7 @@ FILTERED_STATS_FILE=filtered_stats.$$
 FOUND_STATS_FILE=found_stats.$$
 REST_STATS_FILE=rest_stats.$$
 
-DEBUG=0
+DEBUG=1
 
 # Write stats to $STATS_FILE.
 # Call this when you want to get stats from unbound.
@@ -414,4 +414,98 @@ rrset.cache.count=3
 infra.cache.count=2"
 
 
+if test x$USE_CACHEDB == "x1"; then
+
+# Bring the cachedb configured Unbound up
+kill_pid $UNBOUND_PID  # kill current Unbound
+$PRE/unbound -d -c ub_cachedb.conf >unbound.log 2>&1 &
+UNBOUND_PID=$!
+echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+wait_unbound_up unbound.log
+
+echo
+echo "[ Check cachedb cache miss. ]"
+echo "> dig www.example.com."
+dig @127.0.0.1 -p $UNBOUND_PORT 0ttl.example.com. | tee outfile
+echo "> check answer"
+if grep "0.0.0.1" outfile; then
+       echo "OK"
+else
+       end 1
+fi
+check_stats "\
+total.num.queries=1
+total.num.cachemiss=1
+total.num.cachehits=0
+total.num.recursivereplies=1
+num.query.type.A=1
+num.query.class.IN=1
+num.query.opcode.QUERY=1
+num.query.flags.RD=1
+num.query.flags.AD=1
+num.query.edns.present=1
+num.query.udpout=1
+num.query.cachedb=0
+msg.cache.count=0
+rrset.cache.count=1
+infra.cache.count=1
+num.answer.rcode.NOERROR=1"
+
+echo
+echo "[ Check cachedb cache hit. ]"
+echo "> dig www.example.com."
+dig @127.0.0.1 -p $UNBOUND_PORT 0ttl.example.com. | tee outfile
+echo "> check answer"
+if grep "0.0.0.1" outfile; then
+       echo "OK"
+else
+       end 1
+fi
+check_stats "\
+total.num.queries=1
+total.num.cachemiss=1
+total.num.cachehits=0
+total.num.recursivereplies=1
+num.query.type.A=1
+num.query.class.IN=1
+num.query.opcode.QUERY=1
+num.query.flags.RD=1
+num.query.flags.AD=1
+num.query.edns.present=1
+num.query.udpout=0
+num.query.cachedb=1
+msg.cache.count=1
+rrset.cache.count=1
+infra.cache.count=1
+num.answer.rcode.NOERROR=1"
+
+echo
+echo "[ Check cachedb cache hit with stat reset ]"
+echo "> dig www.example.com."
+dig @127.0.0.1 -p $UNBOUND_PORT 0ttl.example.com. | tee outfile
+echo "> check answer"
+if grep "0.0.0.1" outfile; then
+       echo "OK"
+else
+       end 1
+fi
+check_stats "\
+total.num.queries=1
+total.num.cachemiss=0
+total.num.cachehits=1
+total.num.recursivereplies=0
+num.query.type.A=1
+num.query.class.IN=1
+num.query.opcode.QUERY=1
+num.query.flags.RD=1
+num.query.flags.AD=1
+num.query.edns.present=1
+num.query.cachedb=0
+msg.cache.count=1
+rrset.cache.count=1
+infra.cache.count=1
+num.answer.rcode.NOERROR=1"
+
+fi  # USE_CACHEDB
+
 end 0
index 6691b01998add67b847ce90589092a0cf870922c..12df8a93905a2dccd55a6ca95fad4e9c357ea62a 100644 (file)
@@ -21,3 +21,13 @@ SECTION QUESTION
 SECTION ANSWER
 1ttl   1 IN    A 1.1.1.1
 ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+0ttl   IN      A
+SECTION ANSWER
+0ttl   0 IN    A 0.0.0.1
+ENTRY_END
diff --git a/testdata/stat_values.tdir/stat_values_cachedb.conf b/testdata/stat_values.tdir/stat_values_cachedb.conf
new file mode 100644 (file)
index 0000000..b5e9b0e
--- /dev/null
@@ -0,0 +1,36 @@
+server:
+       verbosity: 5
+       module-config: "cachedb iterator"
+       serve-expired: yes
+       num-threads: 1
+       interface: 127.0.0.1
+       port: @PORT@
+       use-syslog: no
+       directory: ""
+       pidfile: "unbound.pid"
+       chroot: ""
+       username: ""
+       do-not-query-localhost: no
+       extended-statistics: yes
+       identity: "stat_values"
+       outbound-msg-retry: 0
+       root-key-sentinel: no
+       trust-anchor-signaling: no
+
+       local-zone: local.zone static
+       local-data: "www.local.zone A 192.0.2.1"
+remote-control:
+       control-enable: yes
+       control-interface: 127.0.0.1
+       # control-interface: ::1
+       control-port: @CONTROL_PORT@
+       server-key-file: "unbound_server.key"
+       server-cert-file: "unbound_server.pem"
+       control-key-file: "unbound_control.key"
+       control-cert-file: "unbound_control.pem"
+forward-zone:
+       name: "."
+       forward-addr: "127.0.0.1@@TOPORT@"
+forward-zone:
+       name: "expired."
+       forward-addr: "127.0.0.1@@EXPIREDPORT@"
index bcb0ccb2e62fc18f73cd1651041befbc87e4b023..dc6835364e167eb021af506ecf8fe9545d24028f 100644 (file)
@@ -677,6 +677,8 @@ struct module_qstate {
         * those servers. By comparing expiry time with qstarttime for type NS.
         */
        time_t qstarttime;
+       /** whether a message from cachedb will be used for the reply */
+       int is_cachedb_answer;
 
        /**
         * Attributes of clients that share the qstate that may affect IP-based