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";
}
}
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)
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);
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);
* 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
repevt_infra_rtt,
/** flush message cache entry */
repevt_flush_message,
+ /** expire message cache entry */
+ repevt_expire_message,
/** cause traffic to flow */
repevt_traffic
}
SCENARIO_BEGIN Test cachedb and serve expired.
; K.ROOT-SERVERS.NET.
-RANGE_BEGIN 0 300
+RANGE_BEGIN 0 400
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
RANGE_END
; a.gtld-servers.net.
-RANGE_BEGIN 0 300
+RANGE_BEGIN 0 400
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode subdomain
RANGE_END
; ns2.example.com.
-RANGE_BEGIN 0 300
+RANGE_BEGIN 0 400
ADDRESS 1.2.3.5
ENTRY_BEGIN
MATCH opcode qname qtype
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
+; expire the entry in cache
+STEP 220 EXPIRE_MESSAGE www.example.com. IN A
+
+; cache is expired, cachedb valid
+STEP 230 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 240 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 250 TIME_PASSES ELAPSE 20
+; expire the entry in cache
+STEP 260 EXPIRE_MESSAGE www.example.com. IN A
+
+; cache is expired, cachedb is expired
+STEP 270 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 280 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 290 TRAFFIC
+; the expired message is updated.
+
+; cache is valid, cachedb is valid
+STEP 300 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+STEP 310 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