From: George Thessalonikefs Date: Tue, 30 May 2023 15:49:50 +0000 (+0200) Subject: - Introduce num.query.cachedb to track cache hits for the external cache. X-Git-Tag: release-1.18.0rc1~24^2~24^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f52be4db977aae9f20faba057a17580630045f9;p=thirdparty%2Funbound.git - Introduce num.query.cachedb to track cache hits for the external cache. --- diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c index 245daa986..36995d6c5 100644 --- a/cachedb/cachedb.c +++ b/cachedb/cachedb.c @@ -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 */ diff --git a/daemon/remote.c b/daemon/remote.c index 03daa935e..d89ecd165 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -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; } diff --git a/daemon/stats.c b/daemon/stats.c index cef7de827..405d8589e 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -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; isvr.qtype[i] += a->svr.qtype[i]; for(i=0; i Number of queries answered using configured RPZ policy, per RPZ action type. diff --git a/libunbound/unbound.h b/libunbound/unbound.h index 8a97b16fe..97be66a88 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -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 */ diff --git a/services/mesh.c b/services/mesh.c index bff0c03e6..22defd580 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -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); } } diff --git a/services/mesh.h b/services/mesh.h index 25121a67b..b83a3df5c 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -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 */ diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index bbc09659f..891ce23ac 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -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 */ diff --git a/testdata/stat_values.tdir/stat_values.pre b/testdata/stat_values.tdir/stat_values.pre index 2db4a17e0..ad1166a06 100644 --- a/testdata/stat_values.tdir/stat_values.pre +++ b/testdata/stat_values.tdir/stat_values.pre @@ -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 diff --git a/testdata/stat_values.tdir/stat_values.test b/testdata/stat_values.tdir/stat_values.test index ef86a0471..60b625279 100644 --- a/testdata/stat_values.tdir/stat_values.test +++ b/testdata/stat_values.tdir/stat_values.test @@ -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 diff --git a/testdata/stat_values.tdir/stat_values.testns b/testdata/stat_values.tdir/stat_values.testns index 6691b0199..12df8a939 100644 --- a/testdata/stat_values.tdir/stat_values.testns +++ b/testdata/stat_values.tdir/stat_values.testns @@ -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 index 000000000..b5e9b0e02 --- /dev/null +++ b/testdata/stat_values.tdir/stat_values_cachedb.conf @@ -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@" diff --git a/util/module.h b/util/module.h index bcb0ccb2e..dc6835364 100644 --- a/util/module.h +++ b/util/module.h @@ -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