]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Add test for cachedb serve expired.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 10 Apr 2024 10:36:21 +0000 (12:36 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 10 Apr 2024 10:36:21 +0000 (12:36 +0200)
Makefile.in
doc/Changelog
testcode/fake_event.c
testcode/replay.c
testcode/replay.h
testcode/testbound.c
testdata/cachedb_expired.crpl [new file with mode: 0644]

index 22fb75c123bdacc72c3138a897d38eaa19b698ec..d1da0f375417c0033eeb41ceaaf013e25d68c61d 100644 (file)
@@ -1355,7 +1355,7 @@ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/test
  $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
  $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
  $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+ $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h $(srcdir)/daemon/worker.h
 testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
  $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
@@ -1428,7 +1428,7 @@ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/t
  $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
  $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
  $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/daemon/remote.h
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/daemon/remote.h $(srcdir)/storage/slabhash.h $(srcdir)/daemon/daemon.h
 lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
   $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
index 421505d96e073f011ad4f8999e2d876c47ed7a7d..c28d2517cfd9a5c5c02e3538a498366efa65a81c 100644 (file)
@@ -3,6 +3,7 @@
          is enabled. When serve expired is enabled with cachedb, it first
          checks cachedb before serving the expired response.
        - Fixup compile without cachedb.
+       - Add test for cachedb serve expired.
 
 9 April 2024: Yorgos
        - Merge #1043 from xiaoxiaoafeifei: Add loongarch support; updates
index 13970c37726a789a8a298b6eb01acc01befe195d..053f88569fc9f91a0c196d5344a48af20449da86 100644 (file)
@@ -52,6 +52,7 @@
 #include "util/data/msgreply.h"
 #include "util/data/msgencode.h"
 #include "util/data/dname.h"
+#include "util/storage/slabhash.h"
 #include "util/edns.h"
 #include "util/config_file.h"
 #include "services/listen_dnsport.h"
@@ -65,6 +66,7 @@
 #include "sldns/wire2str.h"
 #include "sldns/str2wire.h"
 #include "daemon/remote.h"
+#include "daemon/daemon.h"
 #include "util/timeval_func.h"
 #include <signal.h>
 struct worker;
@@ -154,6 +156,7 @@ repevt_string(enum replay_event_type t)
        case repevt_assign:      return "ASSIGN";
        case repevt_traffic:     return "TRAFFIC";
        case repevt_infra_rtt:   return "INFRA_RTT";
+       case repevt_flush_message: return "FLUSH_MESSAGE";
        default:                 return "UNKNOWN";
        }
 }
@@ -691,6 +694,30 @@ do_infra_rtt(struct replay_runtime* runtime)
        free(dp);
 }
 
+/** Flush message from message cache. */
+static void
+do_flush_message(struct replay_runtime* runtime)
+{
+       struct replay_moment* now = runtime->now;
+       uint8_t rr[1024];
+       size_t rr_len = sizeof(rr), dname_len = 0;
+       hashvalue_type h;
+       struct query_info k;
+
+       if(sldns_str2wire_rr_question_buf(now->string, rr, &rr_len,
+               &dname_len, NULL, 0, NULL, 0) != 0)
+               fatal_exit("could not parse '%s'", now->string);
+
+       log_info("remove message %s", now->string);
+       k.qname = rr;
+       k.qname_len = dname_len;
+       k.qtype = sldns_wirerr_get_type(rr, rr_len, dname_len);
+       k.qclass = sldns_wirerr_get_class(rr, rr_len, dname_len);
+       k.local_alias = NULL;
+       h = query_info_hash(&k, 0);
+       slabhash_remove(runtime->daemon->env->msg_cache, h, &k);
+}
+
 /** perform exponential backoff on the timeout */
 static void
 expon_timeout_backoff(struct replay_runtime* runtime)
@@ -796,6 +823,10 @@ do_moment_and_advance(struct replay_runtime* runtime)
                do_infra_rtt(runtime);
                advance_moment(runtime);
                break;
+       case repevt_flush_message:
+               do_flush_message(runtime);
+               advance_moment(runtime);
+               break;
        default:
                fatal_exit("testbound: unknown event type %d",
                        runtime->now->evt_type);
index f896a5512c5d48baa491a9fe98570209a561ddb8..813e74ca4be32b24ba9bb307cc2c790eaef4c58d 100644 (file)
@@ -348,6 +348,13 @@ replay_moment_read(char* remain, FILE* in, const char* name,
                mom->string = strdup(m);
                if(!mom->string) fatal_exit("out of memory");
                if(!mom->variable) fatal_exit("out of memory");
+       } else if(parse_keyword(&remain, "FLUSH_MESSAGE")) {
+               mom->evt_type = repevt_flush_message;
+               while(isspace((unsigned char)*remain))
+                       remain++;
+               strip_end_white(remain);
+               mom->string = strdup(remain);
+               if(!mom->string) fatal_exit("out of memory");
        } else {
                log_err("%d: unknown event type %s", pstate->lineno, remain);
                free(mom);
index 0271dff0393b466476366d60e5e9ec5d24134f17..5f5d410b8f1e48882ccfecacfae68f68fdc1163e 100644 (file)
@@ -85,6 +85,7 @@
  *             The file contents is macro expanded before match.
  *     o CHECK_TEMPFILE [fname] - followed by FILE_BEGIN [to match] FILE_END
  *     o INFRA_RTT [ip] [dp] [rtt] - update infra cache entry with rtt.
+ *     o FLUSH_MESSAGE name type class - flushes entry in message cache.
  *     o ERROR
  * ; following entry starts on the next line, ENTRY_BEGIN.
  * ; more STEP items
@@ -148,6 +149,7 @@ struct fake_timer;
 struct replay_var;
 struct infra_cache;
 struct sldns_buffer;
+struct daemon;
 
 /**
  * A replay scenario.
@@ -212,6 +214,8 @@ struct replay_moment {
                repevt_assign,
                /** store infra rtt cache entry: addr and string (int) */
                repevt_infra_rtt,
+               /** flush message cache entry */
+               repevt_flush_message,
                /** cause traffic to flow */
                repevt_traffic
        }
@@ -297,6 +301,8 @@ struct replay_runtime {
 
        /** ref the infra cache (was passed to outside_network_create) */
        struct infra_cache* infra;
+       /** the daemon structure passed in worker call to remote accept open */
+       struct daemon* daemon;
 
        /** the current time in seconds */
        time_t now_secs;
index ec627cc8deb15cf248f5831e25071c9763a296c9..f023860e086e9be8dd5a50db20584567a775b1d6 100644 (file)
@@ -48,6 +48,7 @@
 #include "testcode/fake_event.h"
 #include "daemon/remote.h"
 #include "libunbound/worker.h"
+#include "daemon/worker.h"
 #include "util/config_file.h"
 #include "sldns/keyraw.h"
 #ifdef UB_ON_WINDOWS
@@ -532,9 +533,10 @@ void daemon_remote_clear(struct daemon_remote* ATTR_UNUSED(rc))
 }
 
 int daemon_remote_open_accept(struct daemon_remote* ATTR_UNUSED(rc),
-        struct listen_port* ATTR_UNUSED(ports), 
-       struct worker* ATTR_UNUSED(worker))
+        struct listen_port* ATTR_UNUSED(ports), struct worker* worker)
 {
+       struct replay_runtime* runtime = (struct replay_runtime*)worker->base;
+       runtime->daemon = worker->daemon;
        return 1;
 }
 
diff --git a/testdata/cachedb_expired.crpl b/testdata/cachedb_expired.crpl
new file mode 100644 (file)
index 0000000..8f9c126
--- /dev/null
@@ -0,0 +1,259 @@
+; config options
+server:
+       target-fetch-policy: "0 0 0 0 0"
+       qname-minimisation: no
+       minimal-responses: no
+       serve-expired: yes
+       module-config: "cachedb iterator"
+
+cachedb:
+       backend: "testframe"
+       secret-seed: "testvalue"
+       cachedb-check-when-serve-expired: yes
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129
+CONFIG_END
+
+SCENARIO_BEGIN Test cachedb and serve expired.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 300
+       ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.     IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 300
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns2.example.com.
+SECTION ADDITIONAL
+ns2.example.com.       IN      A       1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+foo.com. IN NS
+SECTION AUTHORITY
+foo.com. IN NS ns.example.com.
+ENTRY_END
+RANGE_END
+
+; ns2.example.com.
+RANGE_BEGIN 0 300
+       ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qname qtype
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example.com. IN A
+SECTION ANSWER
+www2.example.com. 10 IN A 1.2.3.5
+ENTRY_END
+RANGE_END
+
+; Get an entry in cache, to make it expired.
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; get the answer for it
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 1.2.3.4
+ENTRY_END
+
+; Get another query in cache to make it expired.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www2.example.com. IN A
+ENTRY_END
+
+; get the answer for it
+STEP 30 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www2.example.com. IN A
+SECTION ANSWER
+www2.example.com. 10 IN A 1.2.3.5
+ENTRY_END
+
+; it is now expired
+STEP 40 TIME_PASSES ELAPSE 20
+
+; cache is expired, and cachedb is expired.
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www2.example.com. IN A
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www2.example.com. IN A
+SECTION ANSWER
+www2.example.com. 0 IN A 1.2.3.5
+ENTRY_END
+
+; cache is expired, cachedb has no answer
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 80 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 30 IN A 1.2.3.4
+ENTRY_END
+
+STEP 90 TRAFFIC
+; the entry should be refreshed in cache now.
+; cache is valid and cachedb is valid.
+STEP 100 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 110 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 1.2.3.4
+ENTRY_END
+
+; flush the entry from cache
+STEP 120 FLUSH_MESSAGE www.example.com. IN A
+
+; cache has no answer, cachedb valid
+STEP 130 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 140 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 1.2.3.4
+ENTRY_END
+
+; it is now expired
+STEP 150 TIME_PASSES ELAPSE 20
+; flush the entry from cache
+STEP 160 FLUSH_MESSAGE www.example.com. IN A
+
+; cache has no answer, cachedb is expired
+STEP 170 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 180 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 0 IN A 1.2.3.4
+ENTRY_END
+
+STEP 190 TRAFFIC
+; the expired message is updated.
+
+; cache is valid, cachedb is valid
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 210 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 10 IN A 1.2.3.4
+ENTRY_END
+
+SCENARIO_END