aboutsummaryrefslogtreecommitdiff
path: root/testcode
diff options
context:
space:
mode:
Diffstat (limited to 'testcode')
-rw-r--r--testcode/checklocks.c24
-rw-r--r--testcode/fake_event.c72
-rw-r--r--testcode/replay.c14
-rw-r--r--testcode/replay.h9
-rw-r--r--testcode/testbound.c6
5 files changed, 123 insertions, 2 deletions
diff --git a/testcode/checklocks.c b/testcode/checklocks.c
index 1b5ef282b5e4..d1c877467307 100644
--- a/testcode/checklocks.c
+++ b/testcode/checklocks.c
@@ -68,6 +68,17 @@ static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS];
int check_locking_order = 1;
/** the pid of this runset, reasonably unique. */
static pid_t check_lock_pid;
+/**
+ * Should checklocks print a trace of the lock and unlock calls.
+ * It uses fprintf for that because the log function uses a lock and that
+ * would loop otherwise.
+ */
+static int verbose_locking = 0;
+/**
+ * Assume lock 0 0 (create_thread, create_instance), is the log lock and
+ * do not print for that. Otherwise the output is full of log lock accesses.
+ */
+static int verbose_locking_not_loglock = 1;
/** print all possible debug info on the state of the system */
static void total_debug_info(void);
@@ -508,6 +519,9 @@ checklock_rdlock(enum check_lock_type type, struct checked_lock* lock,
if(key_deleted)
return;
+ if(verbose_locking && !(verbose_locking_not_loglock &&
+ lock->create_thread == 0 && lock->create_instance == 0))
+ fprintf(stderr, "checklock_rdlock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line);
log_assert(type == check_lock_rwlock);
checklock_lockit(type, lock, func, file, line,
try_rd, timed_rd, &lock->u.rwlock, 0, 0);
@@ -528,6 +542,9 @@ checklock_wrlock(enum check_lock_type type, struct checked_lock* lock,
if(key_deleted)
return;
log_assert(type == check_lock_rwlock);
+ if(verbose_locking && !(verbose_locking_not_loglock &&
+ lock->create_thread == 0 && lock->create_instance == 0))
+ fprintf(stderr, "checklock_wrlock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line);
checklock_lockit(type, lock, func, file, line,
try_wr, timed_wr, &lock->u.rwlock, 0, 1);
}
@@ -565,6 +582,9 @@ checklock_lock(enum check_lock_type type, struct checked_lock* lock,
if(key_deleted)
return;
log_assert(type != check_lock_rwlock);
+ if(verbose_locking && !(verbose_locking_not_loglock &&
+ lock->create_thread == 0 && lock->create_instance == 0))
+ fprintf(stderr, "checklock_lock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line);
switch(type) {
case check_lock_mutex:
checklock_lockit(type, lock, func, file, line,
@@ -602,6 +622,10 @@ checklock_unlock(enum check_lock_type type, struct checked_lock* lock,
if(lock->hold_count <= 0)
lock_error(lock, func, file, line, "too many unlocks");
+ if(verbose_locking && !(verbose_locking_not_loglock &&
+ lock->create_thread == 0 && lock->create_instance == 0))
+ fprintf(stderr, "checklock_unlock lock %d %d %s:%d at %s:%d\n", lock->create_thread, lock->create_instance, lock->create_file, lock->create_line, file, line);
+
/* store this point as last touched by */
lock->holder = thr;
lock->hold_count --;
diff --git a/testcode/fake_event.c b/testcode/fake_event.c
index 13970c37726a..09269289dd44 100644
--- a/testcode/fake_event.c
+++ b/testcode/fake_event.c
@@ -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,8 @@ 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";
+ case repevt_expire_message: return "EXPIRE_MESSAGE";
default: return "UNKNOWN";
}
}
@@ -691,6 +695,66 @@ 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);
+}
+
+/** Expire message from message cache. */
+static void
+do_expire_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;
+ struct lruhash_entry* e;
+
+ 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("expire 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);
+
+ e = slabhash_lookup(runtime->daemon->env->msg_cache, h, &k, 0);
+ if(e) {
+ struct msgreply_entry* msg = (struct msgreply_entry*)e->key;
+ struct reply_info* rep = (struct reply_info*)msg->entry.data;
+ time_t expired = runtime->now_secs;
+ expired -= 3;
+ rep->ttl = expired;
+ rep->prefetch_ttl = expired;
+ rep->serve_expired_ttl = expired;
+ lock_rw_unlock(&msg->entry.lock);
+ }
+}
+
/** perform exponential backoff on the timeout */
static void
expon_timeout_backoff(struct replay_runtime* runtime)
@@ -796,6 +860,14 @@ 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;
+ case repevt_expire_message:
+ do_expire_message(runtime);
+ advance_moment(runtime);
+ break;
default:
fatal_exit("testbound: unknown event type %d",
runtime->now->evt_type);
diff --git a/testcode/replay.c b/testcode/replay.c
index f896a5512c5d..95dde405f641 100644
--- a/testcode/replay.c
+++ b/testcode/replay.c
@@ -348,6 +348,20 @@ 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 if(parse_keyword(&remain, "EXPIRE_MESSAGE")) {
+ mom->evt_type = repevt_expire_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);
diff --git a/testcode/replay.h b/testcode/replay.h
index 0271dff0393b..809e8ee39778 100644
--- a/testcode/replay.h
+++ b/testcode/replay.h
@@ -85,6 +85,8 @@
* 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 EXPIRE_MESSAGE name type class - expires entry in message cache.
* o ERROR
* ; following entry starts on the next line, ENTRY_BEGIN.
* ; more STEP items
@@ -148,6 +150,7 @@ struct fake_timer;
struct replay_var;
struct infra_cache;
struct sldns_buffer;
+struct daemon;
/**
* A replay scenario.
@@ -212,6 +215,10 @@ struct replay_moment {
repevt_assign,
/** store infra rtt cache entry: addr and string (int) */
repevt_infra_rtt,
+ /** flush message cache entry */
+ repevt_flush_message,
+ /** expire message cache entry */
+ repevt_expire_message,
/** cause traffic to flow */
repevt_traffic
}
@@ -297,6 +304,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;
diff --git a/testcode/testbound.c b/testcode/testbound.c
index ec627cc8deb1..f023860e086e 100644
--- a/testcode/testbound.c
+++ b/testcode/testbound.c
@@ -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;
}