diff --git a/daemon/remote.c b/daemon/remote.c index 9c87a2e7e..8f00a5440 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1168,7 +1168,6 @@ do_flush_zone(SSL* ssl, struct worker* worker, char* arg) int nmlabs; size_t nmlen; struct del_info inf; - int idx; if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) return; /* delete all RRs and key entries from zone */ @@ -1188,10 +1187,9 @@ do_flush_zone(SSL* ssl, struct worker* worker, char* arg) slabhash_traverse(worker->env.msg_cache, 1, &zone_del_msg, &inf); /* and validator cache */ - idx = modstack_find(&worker->daemon->mods, "validator"); - if(idx != -1) { - struct val_env* ve = (struct val_env*)worker->env.modinfo[idx]; - slabhash_traverse(ve->kcache->slab, 1, &zone_del_kcache, &inf); + if(worker->env.key_cache) { + slabhash_traverse(worker->env.key_cache->slab, 1, + &zone_del_kcache, &inf); } free(nm); diff --git a/doc/Changelog b/doc/Changelog index 26568d2f9..c59da3ff1 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 1 September 2009: Wouter - testbound variable arithmetic. - autotrust probe time is randomised. + - autotrust: the probe is active and does not fetch from cache. 31 August 2009: Wouter - testbound variable processing. diff --git a/testcode/fake_event.c b/testcode/fake_event.c index e6a80b970..aa4093fa0 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -460,11 +460,21 @@ static void time_passes(struct replay_runtime* runtime, struct replay_moment* mom) { struct fake_timer *t; - timeval_add(&runtime->now_tv, &mom->elapse); + struct timeval tv = mom->elapse; + if(mom->string) { + char* xp = macro_process(runtime->vars, runtime, mom->string); + double sec; + if(!xp) fatal_exit("could not macro expand %s", mom->string); + verbose(VERB_ALGO, "EVAL %s", mom->string); + sec = atof(xp); + tv.tv_sec = (int)sec; + tv.tv_usec = (int)((sec - (double)tv.tv_sec) *1000000. + 0.5); + } + timeval_add(&runtime->now_tv, &tv); runtime->now_secs = (uint32_t)runtime->now_tv.tv_sec; #ifndef S_SPLINT_S log_info("elapsed %d.%6.6d now %d.%6.6d", - (int)mom->elapse.tv_sec, (int)mom->elapse.tv_usec, + (int)tv.tv_sec, (int)tv.tv_usec, (int)runtime->now_tv.tv_sec, (int)runtime->now_tv.tv_usec); #endif /* see if any timers have fired; and run them */ diff --git a/testcode/replay.c b/testcode/replay.c index ca55660d1..322ce5c23 100644 --- a/testcode/replay.c +++ b/testcode/replay.c @@ -301,6 +301,16 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, mom->evt_type = repevt_timeout; } else if(parse_keyword(&remain, "TIME_PASSES")) { mom->evt_type = repevt_time_passes; + while(isspace((int)*remain)) + remain++; + if(parse_keyword(&remain, "EVAL")) { + while(isspace((int)*remain)) + remain++; + mom->string = strdup(remain); + if(!mom->string) fatal_exit("out of memory"); + mom->string[strlen(mom->string)-1]=0; + remain += strlen(mom->string); + } } else if(parse_keyword(&remain, "CHECK_AUTOTRUST")) { mom->evt_type = repevt_autotrust_check; while(isspace((int)*remain)) diff --git a/testcode/replay.h b/testcode/replay.h index 4237643ce..c1236d9d2 100644 --- a/testcode/replay.h +++ b/testcode/replay.h @@ -69,6 +69,7 @@ * o TIMEOUT * o TIME_PASSES ELAPSE [seconds] - increase 'now' time counter, can be * a floating point number. + * TIME_PASSES EVAL [macro] - expanded for seconds to move time. * o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END. * The file contents is macro expanded before match. * o ERROR diff --git a/testdata/autotrust_init.rpl b/testdata/autotrust_init.rpl index 56a93fab1..1c6eeb2e2 100644 --- a/testdata/autotrust_init.rpl +++ b/testdata/autotrust_init.rpl @@ -156,4 +156,42 @@ FILE_BEGIN example.com. 10800 IN DNSKEY 257 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55582 (ksk), size = 512b} ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1251100000 ;;Mon Aug 24 09:46:40 2009 FILE_END +; wait and see if autotrust probes (the unchanged) domain again. +STEP 40 TIME_PASSES EVAL ${$probe} + +; do something to make time pass so that processing is performed. +STEP 50 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +. IN NS +ENTRY_END + +STEP 60 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. 3600 IN NS k.root-servers.net. +SECTION ADDITIONAL +k.root-servers.net. 3600 IN A 193.0.14.129 +ENTRY_END + +STEP 65 ASSIGN probe2 = ${timeout} + +STEP 70 CHECK_AUTOTRUST example.com +FILE_BEGIN +; autotrust trust anchor file +;;id: example.com. 1 +;;last_queried: ${time} ;;${ctime ${time}} +;;last_success: ${time} ;;${ctime ${time}} +;;next_probe_time: ${$t0 + $probe + $probe2} ;;${ctime $t0 + $probe + $probe2} +;;query_failed: 0 +;;query_interval: 5400 +;;retry_time: 3600 +example.com. 10800 IN DNSKEY 257 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55582 (ksk), size = 512b} ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1251100000 ;;Mon Aug 24 09:46:40 2009 +FILE_END + SCENARIO_END diff --git a/util/module.h b/util/module.h index 736956716..8c430affa 100644 --- a/util/module.h +++ b/util/module.h @@ -46,6 +46,7 @@ #include "util/data/msgparse.h" struct alloc_cache; struct rrset_cache; +struct key_cache; struct config_file; struct slabhash; struct query_info; @@ -77,6 +78,8 @@ struct module_env { struct rrset_cache* rrset_cache; /** shared infrastructure cache (edns, lameness) */ struct infra_cache* infra_cache; + /** shared key cache */ + struct key_cache* key_cache; /* --- services --- */ /** diff --git a/validator/autotrust.c b/validator/autotrust.c index 9b57597bd..ba669f95b 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -54,6 +54,8 @@ #include "util/random.h" #include "util/data/msgparse.h" #include "services/mesh.h" +#include "services/cache/rrset.h" +#include "validator/val_kcache.h" #include "daemon/worker.h" /** number of times a key must be seen before it can become valid */ @@ -1630,12 +1632,13 @@ int autr_process_prime(struct module_env* env, struct val_env* ve, return 1; /* trust point unchanged, so exists */ } + autr_cleanup_keys(tp); + if(!set_next_probe(env, tp, dnskey_rrset)) + return 0; /* trust point does not exist */ + verbose(VERB_ALGO, "autotrust: write to disk"); + autr_write_file(env, tp); if(changed) { - autr_cleanup_keys(tp); - if(!set_next_probe(env, tp, dnskey_rrset)) - return 0; /* trust point does not exist */ - verbose(VERB_ALGO, "autotrust: point changed, write to disk"); - autr_write_file(env, tp); + verbose(VERB_ALGO, "autotrust: changed, reassemble"); if(!autr_assemble(tp)) { log_err("malloc failure assembling autotrust keys"); return 1; /* unchanged */ @@ -1777,6 +1780,15 @@ probe_anchor(struct module_env* env, struct trust_anchor* tp) /* can't hold the lock while mesh_run is processing */ lock_basic_unlock(&tp->lock); + + /* delete the DNSKEY from rrset and key cache so an active probe + * is done. First the rrset so another thread does not use it + * to recreate the key entry in a race condition. */ + rrset_cache_remove(env->rrset_cache, qinfo.qname, qinfo.qname_len, + qinfo.qtype, qinfo.qclass, 0); + key_cache_remove(env->key_cache, qinfo.qname, qinfo.qname_len, + qinfo.qclass); + if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, &probe_answer_cb, env)) { log_err("out of memory making 5011 probe"); diff --git a/validator/val_kcache.c b/validator/val_kcache.c index 70267e517..8c4c4997a 100644 --- a/validator/val_kcache.c +++ b/validator/val_kcache.c @@ -152,3 +152,14 @@ key_cache_get_mem(struct key_cache* kcache) return sizeof(*kcache) + slabhash_get_mem(kcache->slab); } +void key_cache_remove(struct key_cache* kcache, + uint8_t* name, size_t namelen, uint16_t key_class) +{ + struct key_entry_key lookfor; + lookfor.entry.key = &lookfor; + lookfor.name = name; + lookfor.namelen = namelen; + lookfor.key_class = key_class; + key_entry_hash(&lookfor); + slabhash_remove(kcache->slab, lookfor.entry.hash, &lookfor); +} diff --git a/validator/val_kcache.h b/validator/val_kcache.h index 948353d7d..bc02bce17 100644 --- a/validator/val_kcache.h +++ b/validator/val_kcache.h @@ -78,6 +78,16 @@ void key_cache_delete(struct key_cache* kcache); */ void key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey); +/** + * Remove an entry from the key cache. + * @param kcache: the key cache. + * @param name: for what name to look; uncompressed wireformat + * @param namelen: length of the name. + * @param key_class: class of the key. + */ +void key_cache_remove(struct key_cache* kcache, + uint8_t* name, size_t namelen, uint16_t key_class); + /** * Lookup key entry in the cache. Looks up the closest key entry above the * given name. diff --git a/validator/validator.c b/validator/validator.c index 42ba0a88f..2e33fd007 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -118,6 +118,7 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env, log_err("out of memory"); return 0; } + env->key_cache = val_env->kcache; if(!anchors_apply_cfg(env->anchors, cfg)) { log_err("validator: error in trustanchors config"); return 0;