Faster due to time-sharing.

git-svn-id: file:///svn/unbound/trunk@966 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-02-19 13:12:23 +00:00
parent 0866b8e60b
commit b2710818d4
34 changed files with 278 additions and 139 deletions

View File

@ -406,7 +406,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
*/
uint16_t udpsize = edns->udp_size;
int secure = 0;
uint32_t timenow = (uint32_t)time(0);
uint32_t timenow = *worker->env.now;
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
struct dns_msg *msg = NULL;
struct delegpt *dp;
@ -510,7 +510,7 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
{
struct msgreply_entry* mrentry = (struct msgreply_entry*)e->key;
struct reply_info* rep = (struct reply_info*)e->data;
uint32_t timenow = time(0);
uint32_t timenow = *worker->env.now;
uint16_t udpsize = edns->udp_size;
int secure;
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
@ -1008,6 +1008,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker->thread_num);
alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
worker->env = *worker->daemon->env;
comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
if(worker->thread_num == 0)
log_set_time(worker->env.now);
worker->env.worker = worker;
worker->env.send_packet = &worker_send_packet;
worker->env.send_query = &worker_send_query;
@ -1057,6 +1060,8 @@ worker_delete(struct worker* worker)
comm_signal_delete(worker->comsig);
comm_point_delete(worker->cmd_com);
comm_timer_delete(worker->stat_timer);
if(worker->thread_num == 0)
log_set_time(NULL);
comm_base_delete(worker->base);
ub_randfree(worker->rndstate);
/* close fds after deleting commpoints, to be sure.

View File

@ -2,6 +2,10 @@
- applied patch to unbound-host man page from Jan-Piet Mens.
- fix donotquery-localhost: yes default (it erroneously was switched
to default 'no').
- time is only gotten once and the value is shared across unbound.
- unittest cleans up crypto, so that it has no memory leaks.
- mini_event shares the time value with unbound this results in
+3% speed for cache responses and +9% for recursions.
18 February 2008: Wouter
- patch to unbound-host from Jan-Piet Mens.

View File

@ -467,7 +467,7 @@ store_rrset(ldns_buffer* pkt, struct msg_parse* msg, struct module_env* env,
struct ub_packed_rrset_key* k;
struct packed_rrset_data* d;
struct rrset_ref ref;
uint32_t now = time(NULL);
uint32_t now = *env->now;
k = alloc_special_obtain(env->alloc);
if(!k)

View File

@ -130,7 +130,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
/** filter out unsuitable targets, return rtt or -1 */
static int
iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, time_t now, struct delegpt_addr* a)
uint8_t* name, size_t namelen, uint32_t now, struct delegpt_addr* a)
{
int rtt;
int lame;
@ -160,7 +160,7 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
* returns number of best targets (or 0, no suitable targets) */
static int
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, time_t now, struct delegpt* dp,
uint8_t* name, size_t namelen, uint32_t now, struct delegpt* dp,
int* best_rtt)
{
int got_num = 0, got_rtt = 0, thisrtt, swap_to_front;
@ -211,12 +211,11 @@ iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp,
uint8_t* name, size_t namelen, int* dnssec_expected)
{
time_t now = time(NULL);
int sel;
int selrtt;
struct delegpt_addr* a, *prev;
int num = iter_filter_order(iter_env, env, name, namelen, now, dp,
&selrtt);
int num = iter_filter_order(iter_env, env, name, namelen,
*env->now, dp, &selrtt);
if(num == 0)
return NULL;

View File

@ -759,7 +759,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
* cache needs to be primed for the qclass. */
iq->dp = dns_cache_find_delegation(qstate->env, delname,
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
qstate->region, &iq->deleg_msg, (uint32_t)time(NULL));
qstate->region, &iq->deleg_msg, *qstate->env->now);
/* If the cache has returned nothing, then we have a
* root priming situation. */
@ -1336,8 +1336,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* gotten this from cache, so test to be sure */
if(!infra_set_lame(qstate->env->infra_cache,
&qstate->reply->addr, qstate->reply->addrlen,
iq->dp->name, iq->dp->namelen, time(NULL),
dnsseclame))
iq->dp->name, iq->dp->namelen,
*qstate->env->now, dnsseclame))
log_err("mark host lame: out of memory");
} else log_err("%slame response from cache",
dnsseclame?"DNSSEC ":"");

View File

@ -172,6 +172,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
w->env->attach_sub = &mesh_attach_sub;
w->env->kill_sub = &mesh_state_delete;
w->env->detect_cycle = &mesh_detect_cycle;
comm_base_timept(w->base, &w->env->now, &w->env->now_tv);
return w;
}

17
services/cache/dns.c vendored
View File

@ -52,7 +52,7 @@
/** store rrsets in the rrset cache.
* @param env: module environment with caches.
* @param rep: contains list of rrsets to store.
* @param now: current time(NULL).
* @param now: current time.
*/
static void
store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now)
@ -73,7 +73,7 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_t hash, struct reply_info* rep)
{
struct msgreply_entry* e;
uint32_t now = time(NULL), ttl = rep->ttl;
uint32_t ttl = rep->ttl;
size_t i;
/* store RRsets */
@ -82,8 +82,8 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
rep->ref[i].id = rep->rrsets[i]->id;
}
reply_info_sortref(rep);
reply_info_set_ttls(rep, now);
store_rrsets(env, rep, now);
reply_info_set_ttls(rep, *env->now);
store_rrsets(env, rep, *env->now);
if(ttl == 0) {
/* we do not store the message, but we did store the RRs,
* which could be useful for delegation information */
@ -219,7 +219,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
{
struct delegpt_ns* ns;
struct ub_packed_rrset_key* akey;
uint32_t now = time(NULL);
uint32_t now = *env->now;
for(ns = dp->nslist; ns; ns = ns->next) {
if(ns->resolved)
continue;
@ -543,7 +543,7 @@ dns_cache_lookup(struct module_env* env,
struct lruhash_entry* e;
struct query_info k;
hashvalue_t h;
uint32_t now = (uint32_t)time(NULL);
uint32_t now = *env->now;
struct ub_packed_rrset_key* rrset;
/* lookup first, this has both NXdomains and ANSWER responses */
@ -630,16 +630,15 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
if(is_referral) {
/* store rrsets */
struct rrset_ref ref;
uint32_t now = time(NULL);
size_t i;
for(i=0; i<rep->rrset_count; i++) {
packed_rrset_ttl_add((struct packed_rrset_data*)
rep->rrsets[i]->entry.data, now);
rep->rrsets[i]->entry.data, *env->now);
ref.key = rep->rrsets[i];
ref.id = rep->rrsets[i]->id;
/*ignore ret: it was in the cache, ref updated */
(void)rrset_cache_update(env->rrset_cache, &ref,
env->alloc, now);
env->alloc, *env->now);
}
free(rep);
return 1;

View File

@ -158,7 +158,7 @@ infra_lookup_host_nottl(struct infra_cache* infra,
struct infra_host_data*
infra_lookup_host(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen, int wr,
time_t timenow, struct infra_host_key** key)
uint32_t timenow, struct infra_host_key** key)
{
struct infra_host_data* data;
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
@ -186,7 +186,7 @@ infra_lookup_host(struct infra_cache* infra,
*/
static struct lruhash_entry*
new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, time_t tm)
socklen_t addrlen, uint32_t tm)
{
struct infra_host_data* data;
struct infra_host_key* key = (struct infra_host_key*)malloc(
@ -214,7 +214,7 @@ new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr,
int
infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, time_t timenow, int* edns_vs, int* to)
socklen_t addrlen, uint32_t timenow, int* edns_vs, int* to)
{
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
addrlen, 0);
@ -260,7 +260,7 @@ hash_lameness(uint8_t* name, size_t namelen)
int
infra_lookup_lame(struct infra_host_data* host,
uint8_t* name, size_t namelen, time_t timenow)
uint8_t* name, size_t namelen, uint32_t timenow)
{
struct lruhash_entry* e;
struct infra_lame_key k;
@ -329,7 +329,7 @@ infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg))
int
infra_set_lame(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, time_t timenow, int dnsseclame)
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame)
{
struct infra_host_data* data;
struct lruhash_entry* e;
@ -422,7 +422,7 @@ infra_update_tcp_works(struct infra_cache* infra,
int
infra_rtt_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
int roundtrip, time_t timenow)
int roundtrip, uint32_t timenow)
{
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
addrlen, 1);
@ -452,7 +452,7 @@ infra_rtt_update(struct infra_cache* infra,
int
infra_edns_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
int edns_version, time_t timenow)
int edns_version, uint32_t timenow)
{
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
addrlen, 1);
@ -478,7 +478,7 @@ int
infra_get_lame_rtt(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, int* lame, int* dnsseclame,
int* rtt, time_t timenow)
int* rtt, uint32_t timenow)
{
struct infra_host_data* host;
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,

View File

@ -63,7 +63,7 @@ struct infra_host_key {
*/
struct infra_host_data {
/** TTL value for this entry. absolute time. */
time_t ttl;
uint32_t ttl;
/** round trip times for timeout calculation */
struct rtt_info rtt;
/** Names of the zones that are lame. NULL=no lame zones. */
@ -90,7 +90,7 @@ struct infra_lame_key {
*/
struct infra_lame_data {
/** TTL of this entry. absolute time. */
time_t ttl;
uint32_t ttl;
/** is the host lame (does not serve the zone authoritatively),
* or is the host dnssec lame (does not serve DNSSEC data) */
int isdnsseclame;
@ -151,7 +151,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
*/
struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen, int wr,
time_t timenow, struct infra_host_key** key);
uint32_t timenow, struct infra_host_key** key);
/**
* Find host information to send a packet. Creates new entry if not found.
@ -166,7 +166,7 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
* @return: 0 on error.
*/
int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, time_t timenow, int* edns_vs, int* to);
socklen_t addrlen, uint32_t timenow, int* edns_vs, int* to);
/**
* Check for lameness of this server for a particular zone.
@ -178,7 +178,7 @@ int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
* @return: 0 if not lame or unknown or timed out, 1 if lame, 2 if dnsseclame.
*/
int infra_lookup_lame(struct infra_host_data* host,
uint8_t* name, size_t namelen, time_t timenow);
uint8_t* name, size_t namelen, uint32_t timenow);
/**
* Set a host to be lame for the given zone.
@ -194,7 +194,7 @@ int infra_lookup_lame(struct infra_host_data* host,
*/
int infra_set_lame(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, time_t timenow, int dnsseclame);
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame);
/**
* Update rtt information for the host.
@ -208,7 +208,7 @@ int infra_set_lame(struct infra_cache* infra,
*/
int infra_rtt_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
int roundtrip, time_t timenow);
int roundtrip, uint32_t timenow);
/**
* Update information for the host, store that a TCP transaction works.
@ -230,7 +230,7 @@ void infra_update_tcp_works(struct infra_cache* infra,
*/
int infra_edns_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
int edns_version, time_t timenow);
int edns_version, uint32_t timenow);
/**
* Get Lameness information and average RTT if host is in the cache.
@ -250,7 +250,7 @@ int infra_edns_update(struct infra_cache* infra,
int infra_get_lame_rtt(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, int* lame, int* dnsseclame,
int* rtt, time_t timenow);
int* rtt, uint32_t timenow);
/**
* Get memory used by the infra cache.

View File

@ -309,9 +309,8 @@ rrset_array_unlock_touch(struct rrset_cache* r, struct regional* scratch,
void
rrset_update_sec_status(struct rrset_cache* r,
struct ub_packed_rrset_key* rrset)
struct ub_packed_rrset_key* rrset, uint32_t now)
{
uint32_t now = (uint32_t)time(0);
struct packed_rrset_data* updata =
(struct packed_rrset_data*)rrset->entry.data;
struct lruhash_entry* e;
@ -339,9 +338,8 @@ rrset_update_sec_status(struct rrset_cache* r,
void
rrset_check_sec_status(struct rrset_cache* r,
struct ub_packed_rrset_key* rrset)
struct ub_packed_rrset_key* rrset, uint32_t now)
{
uint32_t now = (uint32_t)time(0);
struct packed_rrset_data* updata =
(struct packed_rrset_data*)rrset->entry.data;
struct lruhash_entry* e;

View File

@ -192,9 +192,10 @@ void rrset_array_unlock_touch(struct rrset_cache* r, struct regional* scratch,
* @param r: the rrset cache.
* @param rrset: which rrset to attempt to update. This rrset is left
* untouched. The rrset in the cache is updated in-place.
* @param now: current time.
*/
void rrset_update_sec_status(struct rrset_cache* r,
struct ub_packed_rrset_key* rrset);
struct ub_packed_rrset_key* rrset, uint32_t now);
/**
* Looks up security status of an rrset. Looks up the rrset.
@ -203,9 +204,10 @@ void rrset_update_sec_status(struct rrset_cache* r,
* @param r: the rrset cache.
* @param rrset: This rrset may change security status due to the cache.
* But its status will only improve, towards secure.
* @param now: current time.
*/
void rrset_check_sec_status(struct rrset_cache* r,
struct ub_packed_rrset_key* rrset);
struct ub_packed_rrset_key* rrset, uint32_t now);
/** mark rrset to be deleted, set id=0 */
void rrset_markdel(void* key);

View File

@ -516,6 +516,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
struct mesh_reply* r)
{
struct timeval end_time;
struct timeval duration;
int secure;
/* examine security status */
if(m->s.env->need_to_validate && !(r->qflags&BIT_CD) && rep &&
@ -551,18 +552,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
}
/* account */
m->s.env->mesh->num_reply_addrs--;
if(gettimeofday(&end_time, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
return;
} else {
struct timeval duration;
timeval_subtract(&duration, &end_time, &r->start_time);
verbose(VERB_ALGO, "query took %d.%6.6d sec",
(int)duration.tv_sec, (int)duration.tv_usec);
m->s.env->mesh->replies_sent++;
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
timehist_insert(m->s.env->mesh->histogram, &duration);
}
end_time = *m->s.env->now_tv;
timeval_subtract(&duration, &end_time, &r->start_time);
verbose(VERB_ALGO, "query took %d.%6.6d sec",
(int)duration.tv_sec, (int)duration.tv_usec);
m->s.env->mesh->replies_sent++;
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
timehist_insert(m->s.env->mesh->histogram, &duration);
}
void mesh_query_done(struct mesh_state* mstate)
@ -640,10 +636,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
r->edns = *edns;
r->qid = qid;
r->qflags = qflags;
if(gettimeofday(&r->start_time, NULL) < 0) {
log_err("addrep: gettimeofday: %s", strerror(errno));
memset(&r->start_time, 0, sizeof(r->start_time));
}
r->start_time = *s->s.env->now_tv;
r->next = s->reply_list;
s->reply_list = r;
return 1;

View File

@ -430,6 +430,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
log_err("malloc failed");
return NULL;
}
comm_base_timept(base, &outnet->now_secs, &outnet->now_tv);
outnet->base = base;
outnet->num_tcp = num_tcp;
outnet->infra = infra;
@ -947,7 +948,7 @@ static int
serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
{
int rtt, vs;
time_t now = time(0);
uint32_t now = *sq->outnet->now_secs;
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, now, &vs,
&rtt))
@ -958,10 +959,7 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
else sq->status = serviced_query_UDP;
}
serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS);
if(gettimeofday(&sq->last_sent_time, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
return 0;
}
sq->last_sent_time = *sq->outnet->now_tv;
verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt);
sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr,
sq->addrlen, rtt, serviced_udp_callback, sq, sq->outnet->rnd);
@ -1039,7 +1037,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(ldns_buffer_begin(
c->buffer)) == LDNS_RCODE_NOTIMPL) ) {
if(!infra_edns_update(sq->outnet->infra, &sq->addr,
sq->addrlen, -1, time(0)))
sq->addrlen, -1, *sq->outnet->now_secs))
log_err("Out of memory caching no edns for host");
sq->status = serviced_query_TCP;
serviced_tcp_initiate(sq->outnet, sq, c->buffer);
@ -1079,19 +1077,15 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
{
struct serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet;
struct timeval now;
struct timeval now = *sq->outnet->now_tv;
int fallback_tcp = 0;
if(gettimeofday(&now, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
/* this option does not need current time */
error = NETEVENT_CLOSED;
}
sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) {
int rto = 0;
sq->retry++;
if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
-1, (time_t)now.tv_sec)))
-1, (uint32_t)now.tv_sec)))
log_err("out of memory in UDP exponential backoff");
if(sq->retry < OUTBOUND_UDP_RETRY) {
log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
@ -1115,7 +1109,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) {
/* note no EDNS, fallback without EDNS */
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
-1, (time_t)now.tv_sec)) {
-1, (uint32_t)now.tv_sec)) {
log_err("Out of memory caching no edns for host");
}
sq->status = serviced_query_UDP;
@ -1145,7 +1139,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime);
log_assert(roundtime >= 0);
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
roundtime, (time_t)now.tv_sec))
roundtime, (uint32_t)now.tv_sec))
log_err("out of memory noting rtt.");
}
serviced_callbacks(sq, error, c, rep);

View File

@ -60,6 +60,10 @@ struct infra_cache;
struct outside_network {
/** Base for select calls */
struct comm_base* base;
/** pointer to time in seconds */
uint32_t* now_secs;
/** pointer to time in microseconds */
struct timeval* now_tv;
/** buffer shared by UDP connections, since there is only one
datagram at any time. */

View File

@ -592,6 +592,14 @@ comm_base_delete(struct comm_base* b)
free(runtime);
}
void
comm_base_timept(struct comm_base* b, uint32_t** tt, struct timeval** tv)
{
struct replay_runtime* runtime = (struct replay_runtime*)b;
*tt = &runtime->now_secs;
*tv = &runtime->now_tv;
}
void
comm_base_dispatch(struct comm_base* b)
{

View File

@ -226,6 +226,11 @@ struct replay_runtime {
/** user argument for incoming query callback */
void *cb_arg;
/** the current time in seconds */
uint32_t now_secs;
/** the current time in microseconds */
struct timeval now_tv;
/** signal handler callback */
void (*sig_cb)(int, void*);
/** signal handler user arg */

View File

@ -314,7 +314,7 @@ infra_test()
size_t zonelen = 13;
struct infra_cache* slab;
struct config_file* cfg = config_create();
time_t now = 0;
uint32_t now = 0;
int vs, to;
struct infra_host_key* k;
struct infra_host_data* d;
@ -409,5 +409,7 @@ main(int argc, char* argv[])
msgparse_test();
checklock_stop();
printf("%d checks ok.\n", testcount);
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
return 0;
}

View File

@ -263,6 +263,7 @@ verifytest_file(const char* fname, const char* at_date)
struct entry* list = read_datafile(fname);
struct module_env env;
struct val_env ve;
uint32_t now = time(NULL);
if(!list)
fatal_exit("could not read %s: %s", fname, strerror(errno));
@ -271,6 +272,7 @@ verifytest_file(const char* fname, const char* at_date)
memset(&ve, 0, sizeof(ve));
env.scratch = region;
env.scratch_buffer = buf;
env.now = &now;
ve.date_override = cfg_convert_timeval(at_date);
unit_assert(region && buf);
dnskey = extract_keys(list, &alloc, region, buf);

View File

@ -69,6 +69,8 @@ static const char* ident="unbound";
/** are we using syslog(3) to log to */
static int log_to_syslog = 0;
#endif /* HAVE_SYSLOG_H */
/** time to print in log, if NULL, use time(2) */
static uint32_t* log_now = NULL;
void
log_init(const char* filename, int use_syslog, const char* chrootdir)
@ -130,12 +132,18 @@ void log_ident_set(const char* id)
ident = id;
}
void log_set_time(uint32_t* t)
{
log_now = t;
}
void
log_vmsg(int pri, const char* type,
const char *format, va_list args)
{
char message[MAXSYSLOGMSGLEN];
unsigned int* tid = (unsigned int*)ub_thread_key_get(logkey);
uint32_t now;
(void)pri;
vsnprintf(message, sizeof(message), format, args);
#ifdef HAVE_SYSLOG_H
@ -146,7 +154,10 @@ log_vmsg(int pri, const char* type,
}
#endif /* HAVE_SYSLOG_H */
if(!logfile) return;
fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n", (int)time(NULL),
if(log_now)
now = *log_now;
else now = (uint32_t)time(NULL);
fprintf(logfile, "[%u] %s[%d:%x] %s: %s\n", (unsigned)now,
ident, (int)getpid(), tid?*tid:0, type, message);
fflush(logfile);
}

View File

@ -105,6 +105,13 @@ void log_thread_set(int* num);
*/
void log_ident_set(const char* id);
/**
* Set the time value to print in log entries.
* @param t: the point is copied and used to find the time.
* if NULL, time(2) is used.
*/
void log_set_time(uint32_t* t);
/**
* Log informational message.
* Pass printf formatted arguments. No trailing newline is needed.

View File

@ -67,14 +67,29 @@ int mini_ev_cmp(const void* a, const void* b)
return 0;
}
/** set time */
static int
settime(struct event_base* base)
{
if(gettimeofday(base->time_tv, NULL) < 0) {
return -1;
}
#ifndef S_SPLINT_S
*base->time_secs = (uint32_t)base->time_tv->tv_sec;
#endif
return 0;
}
/** create event base */
void *event_init(void)
void *event_init(uint32_t* time_secs, struct timeval* time_tv)
{
struct event_base* base = (struct event_base*)malloc(
sizeof(struct event_base));
if(!base)
return NULL;
memset(base, 0, sizeof(*base));
base->time_secs = time_secs;
base->time_tv = time_tv;
base->times = rbtree_create(mini_ev_cmp);
if(!base->times) {
event_base_free(base);
@ -165,10 +180,16 @@ static int handle_select(struct event_base* base, struct timeval* wait)
memmove(&w, &base->writes, sizeof(fd_set));
if((ret = select(base->maxfd+1, &r, &w, NULL, wait)) == -1) {
if(errno == EAGAIN || errno == EINTR)
ret = errno;
if(settime(base) < 0)
return -1;
errno = ret;
if(ret == EAGAIN || ret == EINTR)
return 0;
return -1;
}
if(settime(base) < 0)
return -1;
for(i=0; i<base->maxfd+1; i++) {
short bits = 0;
@ -199,13 +220,13 @@ static int handle_select(struct event_base* base, struct timeval* wait)
/** run select in a loop */
int event_base_dispatch(struct event_base* base)
{
struct timeval now, wait;
struct timeval wait;
if(settime(base) < 0)
return -1;
while(!base->need_to_exit)
{
if(gettimeofday(&now, NULL) < 0)
return -1;
/* see if timeouts need handling */
handle_timeouts(base, &now, &wait);
handle_timeouts(base, base->time_tv, &wait);
if(base->need_to_exit)
return 0;
/* do select */
@ -279,11 +300,9 @@ int event_add(struct event* ev, struct timeval* tv)
}
if(tv && (ev->ev_events&EV_TIMEOUT)) {
#ifndef S_SPLINT_S
struct timeval now;
if(gettimeofday(&now, NULL) < 0)
return -1;
ev->ev_timeout.tv_sec = tv->tv_sec + now.tv_sec;
ev->ev_timeout.tv_usec = tv->tv_usec + now.tv_usec;
struct timeval *now = ev->ev_base->time_tv;
ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec;
ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec;
while(ev->ev_timeout.tv_usec > 1000000) {
ev->ev_timeout.tv_usec -= 1000000;
ev->ev_timeout.tv_sec++;

View File

@ -94,6 +94,10 @@ struct event_base
struct event** signals;
/** if we need to exit */
int need_to_exit;
/** where to store time in seconds */
uint32_t* time_secs;
/** where to store time in microseconds */
struct timeval* time_tv;
};
/**
@ -122,7 +126,7 @@ struct event {
/* function prototypes as they appear in event.h */
/** create event base */
void *event_init(void);
void *event_init(uint32_t* time_secs, struct timeval* time_tv);
/** get version */
const char *event_get_version(void);
/** get polling method, select */

View File

@ -191,6 +191,10 @@ struct module_env {
struct alloc_cache* alloc;
/** random table to generate random numbers */
struct ub_randstate* rnd;
/** time in seconds, converted to integer */
uint32_t* now;
/** time in microseconds. Relatively recent. */
struct timeval* now_tv;
/** is validation required for messages, controls client-facing
* validation status (AD bits) and servfails */
int need_to_validate;

View File

@ -62,6 +62,8 @@
* Possibly other structures (list, tree) this is part of.
*/
struct internal_event {
/** the comm base */
struct comm_base* base;
/** libevent event type, alloced here */
struct event ev;
};
@ -72,12 +74,18 @@ struct internal_event {
struct internal_base {
/** libevent event_base type. */
struct event_base* base;
/** seconds time pointer points here */
uint32_t secs;
/** timeval with current time */
struct timeval now;
};
/**
* Internal timer structure, to store timer event in.
*/
struct internal_timer {
/** the comm base */
struct comm_base* base;
/** libevent event type, alloced here */
struct event ev;
/** is timer enabled */
@ -101,6 +109,20 @@ static struct comm_point* comm_point_create_tcp_handler(
/* -------- End of local definitions -------- */
#ifdef USE_MINI_EVENT
#define comm_base_now(x) /* nothing to do */
#else /* !USE_MINI_EVENT */
/** fillup the time values in the event base */
static void
comm_base_now(struct comm_base* b)
{
if(gettimeofday(&b->eb->now, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
}
b->eb->secs = (uint32_t)b->eb->now.tv_sec;
}
#endif /* USE_MINI_EVENT */
struct comm_base*
comm_base_create()
{
@ -113,12 +135,18 @@ comm_base_create()
free(b);
return NULL;
}
#ifdef USE_MINI_EVENT
/* use mini event time-sharing feature */
b->eb->base = event_init(&b->eb->secs, &b->eb->now);
#else
b->eb->base = event_init();
#endif
if(!b->eb->base) {
free(b->eb);
free(b);
return NULL;
}
comm_base_now(b);
verbose(VERB_ALGO, "libevent %s uses %s method.",
event_get_version(), event_get_method());
return b;
@ -142,6 +170,13 @@ comm_base_delete(struct comm_base* b)
free(b);
}
void
comm_base_timept(struct comm_base* b, uint32_t** tt, struct timeval** tv)
{
*tt = &b->eb->secs;
*tv = &b->eb->now;
}
void
comm_base_dispatch(struct comm_base* b)
{
@ -335,6 +370,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
if(!(event&EV_READ))
return;
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
comm_base_now(rep.c->ev->base);
ldns_buffer_clear(rep.c->buffer);
rep.addrlen = (socklen_t)sizeof(rep.addr);
log_assert(fd != -1);
@ -414,6 +450,7 @@ comm_point_udp_callback(int fd, short event, void* arg)
if(!(event&EV_READ))
return;
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
comm_base_now(rep.c->ev->base);
ldns_buffer_clear(rep.c->buffer);
rep.addrlen = (socklen_t)sizeof(rep.addr);
log_assert(fd != -1);
@ -460,6 +497,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
log_info("ignoring tcp accept event %d", (int)event);
return;
}
comm_base_now(c->ev->base);
/* find free tcp handler. */
if(!c->tcp_free) {
log_warn("accepted too many tcp, connections full");
@ -706,6 +744,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
{
struct comm_point* c = (struct comm_point*)arg;
log_assert(c->type == comm_tcp);
comm_base_now(c->ev->base);
if(event&EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 0)) {
@ -748,6 +787,7 @@ void comm_point_local_handle_callback(int fd, short event, void* arg)
{
struct comm_point* c = (struct comm_point*)arg;
log_assert(c->type == comm_local);
comm_base_now(c->ev->base);
if(event&EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 1)) {
@ -765,6 +805,7 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
{
struct comm_point* c = (struct comm_point*)arg;
log_assert(c->type == comm_raw);
comm_base_now(c->ev->base);
(void)(*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, NULL);
}
@ -784,6 +825,7 @@ comm_point_create_udp(struct comm_base *base, int fd, ldns_buffer* buffer,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = fd;
c->buffer = buffer;
c->timeout = NULL;
@ -828,6 +870,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = fd;
c->buffer = buffer;
c->timeout = NULL;
@ -872,6 +915,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = -1;
c->buffer = ldns_buffer_new(bufsize);
if(!c->buffer) {
@ -934,6 +978,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = fd;
c->buffer = NULL;
c->timeout = NULL;
@ -995,6 +1040,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = -1;
c->buffer = ldns_buffer_new(bufsize);
if(!c->buffer) {
@ -1046,6 +1092,7 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = fd;
c->buffer = ldns_buffer_new(bufsize);
if(!c->buffer) {
@ -1097,6 +1144,7 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
free(c);
return NULL;
}
c->ev->base = base;
c->fd = fd;
c->buffer = NULL;
c->timeout = NULL;
@ -1280,6 +1328,7 @@ comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg)
free(tm);
return NULL;
}
tm->ev_timer->base = base;
tm->callback = cb;
tm->cb_arg = cb_arg;
event_set(&tm->ev_timer->ev, -1, EV_PERSIST|EV_TIMEOUT,
@ -1331,6 +1380,7 @@ comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg)
struct comm_timer* tm = (struct comm_timer*)arg;
if(!(event&EV_TIMEOUT))
return;
comm_base_now(tm->ev_timer->base);
tm->ev_timer->enabled = 0;
log_assert(fptr_whitelist_comm_timer(tm->callback));
(*tm->callback)(tm->cb_arg);
@ -1371,6 +1421,7 @@ comm_signal_callback(int sig, short event, void* arg)
struct comm_signal* comsig = (struct comm_signal*)arg;
if(!(event & EV_SIGNAL))
return;
comm_base_now(comsig->base);
log_assert(fptr_whitelist_comm_signal(comsig->callback));
(*comsig->callback)(sig, comsig->cb_arg);
}

View File

@ -264,6 +264,15 @@ struct comm_base* comm_base_create();
*/
void comm_base_delete(struct comm_base* b);
/**
* Obtain two pointers. The pointers never change (until base_delete()).
* The pointers point to time values that are updated regularly.
* @param b: the communication base that will update the time values.
* @param tt: pointer to time in seconds is returned.
* @param tv: pointer to time in microseconds is returned.
*/
void comm_base_timept(struct comm_base* b, uint32_t** tt, struct timeval** tv);
/**
* Dispatch the comm base events.
* @param b: the communication to perform.

View File

@ -119,9 +119,8 @@ key_cache_search(struct key_cache* kcache, uint8_t* name, size_t namelen,
struct key_entry_key*
key_cache_obtain(struct key_cache* kcache, uint8_t* name, size_t namelen,
uint16_t key_class, struct regional* region)
uint16_t key_class, struct regional* region, uint32_t now)
{
uint32_t now = time(NULL);
/* keep looking until we find a nonexpired entry */
while(1) {
struct key_entry_key* k = key_cache_search(kcache, name,

View File

@ -86,13 +86,14 @@ void key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey);
* @param namelen: length of the name.
* @param key_class: class of the key.
* @param region: a copy of the key_entry is allocated in this region.
* @param now: current time.
* @return pointer to a newly allocated key_entry copy in the region, if
* a key entry could be found, and allocation succeeded and TTL was OK.
* Otherwise, NULL is returned.
*/
struct key_entry_key* key_cache_obtain(struct key_cache* kcache,
uint8_t* name, size_t namelen, uint16_t key_class,
struct regional* region);
struct regional* region, uint32_t now);
/**
* Get memory in use by the key cache.

View File

@ -221,13 +221,14 @@ key_entry_setup(struct regional* region,
struct key_entry_key*
key_entry_create_null(struct regional* region,
uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl)
uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl,
uint32_t now)
{
struct key_entry_key* k;
struct key_entry_data* d;
if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
return NULL;
d->ttl = time(0) + ttl;
d->ttl = now + ttl;
d->isbad = 0;
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
d->rrset_data = NULL;
@ -237,7 +238,7 @@ key_entry_create_null(struct regional* region,
struct key_entry_key*
key_entry_create_rrset(struct regional* region,
uint8_t* name, size_t namelen, uint16_t dclass,
struct ub_packed_rrset_key* rrset)
struct ub_packed_rrset_key* rrset, uint32_t now)
{
struct key_entry_key* k;
struct key_entry_data* d;
@ -245,7 +246,7 @@ key_entry_create_rrset(struct regional* region,
rrset->entry.data;
if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
return NULL;
d->ttl = rd->ttl + time(NULL);
d->ttl = rd->ttl + now;
d->isbad = 0;
d->rrset_type = ntohs(rrset->rk.type);
d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,

View File

@ -145,10 +145,12 @@ int key_entry_isbad(struct key_entry_key* kkey);
* @param namelen: length of name
* @param dclass: class of key entry. (host order);
* @param ttl: what ttl should the key have. relative.
* @param now: current time (added to ttl).
* @return new key entry or NULL on alloc failure
*/
struct key_entry_key* key_entry_create_null(struct regional* region,
uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl);
uint8_t* name, size_t namelen, uint16_t dclass, uint32_t ttl,
uint32_t now);
/**
* Create a key entry from an rrset, in the given region.
@ -157,11 +159,12 @@ struct key_entry_key* key_entry_create_null(struct regional* region,
* @param namelen: length of name
* @param dclass: class of key entry. (host order);
* @param rrset: data for key entry. This is copied to the region.
* @param now: current time (added to ttl of rrset)
* @return new key entry or NULL on alloc failure
*/
struct key_entry_key* key_entry_create_rrset(struct regional* region,
uint8_t* name, size_t namelen, uint16_t dclass,
struct ub_packed_rrset_key* rrset);
struct ub_packed_rrset_key* rrset, uint32_t now);
/**
* Create a bad entry, in the given region.

View File

@ -408,7 +408,7 @@ int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
enum sec_status
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey)
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey)
{
enum sec_status sec;
size_t i, num;
@ -420,8 +420,8 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
return sec_status_bogus;
}
for(i=0; i<num; i++) {
sec = dnskeyset_verify_rrset_sig(env, ve, rrset, dnskey, i,
&sortree);
sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset,
dnskey, i, &sortree);
if(sec == sec_status_secure)
return sec;
}
@ -454,8 +454,8 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
continue;
buf_canon = 0;
sec = dnskey_verify_rrset_sig(env->scratch,
env->scratch_buffer, ve, rrset, dnskey, dnskey_idx, i,
&sortree, &buf_canon);
env->scratch_buffer, ve, *env->now, rrset,
dnskey, dnskey_idx, i, &sortree, &buf_canon);
if(sec == sec_status_secure)
return sec;
}
@ -464,9 +464,10 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
}
enum sec_status
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
size_t sig_idx, struct rbtree_t** sortree)
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
uint32_t now, struct ub_packed_rrset_key* rrset,
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
struct rbtree_t** sortree)
{
/* find matching keys and check them */
enum sec_status sec = sec_status_bogus;
@ -486,8 +487,8 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
numchecked ++;
/* see if key verifies */
sec = dnskey_verify_rrset_sig(env->scratch,
env->scratch_buffer, ve, rrset, dnskey, i, sig_idx,
sortree, &buf_canon);
env->scratch_buffer, ve, now, rrset, dnskey, i,
sig_idx, sortree, &buf_canon);
if(sec == sec_status_secure)
return sec;
}
@ -1087,7 +1088,8 @@ sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now)
/** check rrsig dates */
static int
check_dates(struct val_env* ve, uint8_t* expi_p, uint8_t* incep_p)
check_dates(struct val_env* ve, uint32_t unow,
uint8_t* expi_p, uint8_t* incep_p)
{
/* read out the dates */
int32_t expi, incep, now;
@ -1100,7 +1102,7 @@ check_dates(struct val_env* ve, uint8_t* expi_p, uint8_t* incep_p)
if(ve->date_override) {
now = ve->date_override;
verbose(VERB_ALGO, "date override option %d", (int)now);
} else now = (int32_t)time(0);
} else now = (int32_t)unow;
/* check them */
if(incep - expi > 0) {
@ -1123,8 +1125,9 @@ check_dates(struct val_env* ve, uint8_t* expi_p, uint8_t* incep_p)
/** adjust rrset TTL for verified rrset, compare to original TTL and expi */
static void
adjust_ttl(struct val_env* ve, struct ub_packed_rrset_key* rrset,
uint8_t* orig_p, uint8_t* expi_p, uint8_t* incep_p)
adjust_ttl(struct val_env* ve, uint32_t unow,
struct ub_packed_rrset_key* rrset, uint8_t* orig_p,
uint8_t* expi_p, uint8_t* incep_p)
{
struct packed_rrset_data* d =
(struct packed_rrset_data*)rrset->entry.data;
@ -1140,7 +1143,7 @@ adjust_ttl(struct val_env* ve, struct ub_packed_rrset_key* rrset,
/* get current date */
if(ve->date_override) {
now = ve->date_override;
} else now = (int32_t)time(0);
} else now = (int32_t)unow;
expittl = expi - now;
/* so now:
@ -1273,7 +1276,7 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
enum sec_status
dnskey_verify_rrset_sig(struct regional* region, ldns_buffer* buf,
struct val_env* ve,
struct val_env* ve, uint32_t now,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
size_t dnskey_idx, size_t sig_idx,
struct rbtree_t** sortree, int* buf_canon)
@ -1357,7 +1360,7 @@ dnskey_verify_rrset_sig(struct regional* region, ldns_buffer* buf,
/* original ttl, always ok */
/* verify inception, expiration dates */
if(!check_dates(ve, sig+2+8, sig+2+12)) {
if(!check_dates(ve, now, sig+2+8, sig+2+12)) {
return sec_status_bogus;
}
@ -1385,7 +1388,7 @@ dnskey_verify_rrset_sig(struct regional* region, ldns_buffer* buf,
/* check if TTL is too high - reduce if so */
if(sec == sec_status_secure) {
adjust_ttl(ve, rrset, sig+2+4, sig+2+8, sig+2+12);
adjust_ttl(ve, now, rrset, sig+2+4, sig+2+8, sig+2+12);
}
return sec;

View File

@ -164,6 +164,7 @@ enum sec_status dnskey_verify_rrset(struct module_env* env,
* verify rrset, with dnskey rrset, for a specific rrsig in rrset
* @param env: module environment, scratch space is used.
* @param ve: validator environment, date settings.
* @param now: current time for validation (can be overridden).
* @param rrset: to be validated.
* @param dnskey: DNSKEY rrset, keyset to try.
* @param sig_idx: which signature to try to validate.
@ -173,7 +174,7 @@ enum sec_status dnskey_verify_rrset(struct module_env* env,
* or unchecked on error.
*/
enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* rrset,
struct val_env* ve, uint32_t now, struct ub_packed_rrset_key* rrset,
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
struct rbtree_t** sortree);
@ -182,6 +183,7 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
* @param region: scratch region used for temporary allocation.
* @param buf: scratch buffer used for canonicalized rrset data.
* @param ve: validator environment, date settings.
* @param now: current time for validation (can be overridden).
* @param rrset: to be validated.
* @param dnskey: DNSKEY rrset, keyset.
* @param dnskey_idx: which key from the rrset to try.
@ -195,7 +197,7 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
* bogus if it did not validate.
*/
enum sec_status dnskey_verify_rrset_sig(struct regional* region,
ldns_buffer* buf, struct val_env* ve,
ldns_buffer* buf, struct val_env* ve, uint32_t now,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
size_t dnskey_idx, size_t sig_idx,
struct rbtree_t** sortree, int* buf_canon);

View File

@ -322,7 +322,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
return d->security;
}
/* check in the cache if verification has already been done */
rrset_check_sec_status(env->rrset_cache, rrset);
rrset_check_sec_status(env->rrset_cache, rrset, *env->now);
if(d->security == sec_status_secure) {
log_nametypeclass(VERB_ALGO, "verify rrset from cache",
rrset->rk.dname, ntohs(rrset->rk.type),
@ -349,7 +349,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
* if RRset timed out and clients see proper value. */
}
/* if status updated - store in cache for reuse */
rrset_update_sec_status(env->rrset_cache, rrset);
rrset_update_sec_status(env->rrset_cache, rrset, *env->now);
}
return sec;
@ -456,7 +456,8 @@ val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
verbose(VERB_ALGO, "DS matched DNSKEY.");
return key_entry_create_rrset(region,
ds_rrset->rk.dname, ds_rrset->rk.dname_len,
ntohs(ds_rrset->rk.rrset_class), dnskey_rrset);
ntohs(ds_rrset->rk.rrset_class), dnskey_rrset,
*env->now);
}
}
@ -469,7 +470,7 @@ val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
return key_entry_create_null(region, ds_rrset->rk.dname,
ds_rrset->rk.dname_len,
ntohs(ds_rrset->rk.rrset_class),
rrset_get_ttl(ds_rrset));
rrset_get_ttl(ds_rrset), *env->now);
}
/* If any were understandable, then it is bad. */
verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
@ -685,7 +686,7 @@ val_check_nonsecure(struct val_env* ve, struct reply_info* rep)
void
val_mark_indeterminate(struct reply_info* rep, struct val_anchors* anchors,
struct rrset_cache* r)
struct rrset_cache* r, struct module_env* env)
{
size_t i;
struct packed_rrset_data* d;
@ -698,14 +699,14 @@ val_mark_indeterminate(struct reply_info* rep, struct val_anchors* anchors,
{
/* mark as indeterminate */
d->security = sec_status_indeterminate;
rrset_update_sec_status(r, rep->rrsets[i]);
rrset_update_sec_status(r, rep->rrsets[i], *env->now);
}
}
}
void
val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
struct rrset_cache* r)
struct rrset_cache* r, struct module_env* env)
{
size_t i;
struct packed_rrset_data* d;
@ -716,7 +717,7 @@ val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
dname_subdomain_c(rep->rrsets[i]->rk.dname, kkey->name)) {
/* mark as insecure */
d->security = sec_status_insecure;
rrset_update_sec_status(r, rep->rrsets[i]);
rrset_update_sec_status(r, rep->rrsets[i], *env->now);
}
}
}

View File

@ -230,9 +230,11 @@ void val_check_nonsecure(struct val_env* ve, struct reply_info* rep);
* @param rep: the reply with rrsets.
* @param anchors: the trust anchors.
* @param r: rrset cache to store updated security status into.
* @param env: module environment
*/
void val_mark_indeterminate(struct reply_info* rep,
struct val_anchors* anchors, struct rrset_cache* r);
struct val_anchors* anchors, struct rrset_cache* r,
struct module_env* env);
/**
* Mark all unchecked rrset entries below a NULL key entry as insecure.
@ -241,9 +243,10 @@ void val_mark_indeterminate(struct reply_info* rep,
* @param kkey: key entry, key_entry_isnull() for it. A key entry that marks
* the end of secure space into insecure space.
* @param r: rrset cache to store updated security status into.
* @param env: module environment
*/
void val_mark_insecure(struct reply_info* rep, struct key_entry_key* kkey,
struct rrset_cache* r);
struct rrset_cache* r, struct module_env* env);
/**
* Find next unchecked rrset position, return it for skip.

View File

@ -1118,7 +1118,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
}
val_mark_indeterminate(vq->chase_reply, qstate->env->anchors,
qstate->env->rrset_cache);
qstate->env->rrset_cache, qstate->env);
vq->key_entry = NULL;
vq->empty_DS_name = NULL;
vq->ds_rrset = 0;
@ -1176,7 +1176,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
}
vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,
vq->qchase.qclass, qstate->region);
vq->qchase.qclass, qstate->region, *qstate->env->now);
/* if not key, or if keyentry is *above* the trustanchor, i.e.
* the keyentry is based on another (higher) trustanchor */
@ -1196,7 +1196,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
* essentially proven insecure. */
vq->chase_reply->security = sec_status_insecure;
val_mark_insecure(vq->chase_reply, vq->key_entry,
qstate->env->rrset_cache);
qstate->env->rrset_cache, qstate->env);
/* go to finished state to cache this result */
vq->state = VAL_FINISHED_STATE;
return 1;
@ -1357,7 +1357,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
vq->signer_name?"":"unsigned ");
vq->chase_reply->security = sec_status_insecure;
val_mark_insecure(vq->chase_reply, vq->key_entry,
qstate->env->rrset_cache);
qstate->env->rrset_cache, qstate->env);
return 1;
}
@ -1538,7 +1538,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
/* if the result is bogus - set message ttl to bogus ttl to avoid
* endless bogus revalidation */
if(vq->orig_msg->rep->security == sec_status_bogus) {
vq->orig_msg->rep->ttl = time(0) + ve->bogus_ttl;
vq->orig_msg->rep->ttl = *qstate->env->now + ve->bogus_ttl;
/* If we are in permissive mode, bogus gets indeterminate */
if(ve->permissive_mode)
vq->orig_msg->rep->security = sec_status_indeterminate;
@ -1692,7 +1692,8 @@ primeResponseToKE(int rcode, struct dns_msg* msg, struct trust_anchor* ta,
kkey = key_entry_create_bad(qstate->region, ta->name,
ta->namelen, ta->dclass);
else kkey = key_entry_create_null(qstate->region, ta->name,
ta->namelen, ta->dclass, NULL_KEY_TTL);
ta->namelen, ta->dclass, NULL_KEY_TTL,
*qstate->env->now);
if(!kkey) {
log_err("out of memory: allocate fail prime key");
return NULL;
@ -1723,7 +1724,7 @@ primeResponseToKE(int rcode, struct dns_msg* msg, struct trust_anchor* ta,
if(sec == sec_status_secure) {
kkey = key_entry_create_rrset(qstate->region,
ta->name, ta->namelen, ta->dclass,
dnskey_rrset);
dnskey_rrset, *qstate->env->now);
if(!kkey) {
log_err("out of memory: allocate primed key");
return NULL;
@ -1741,7 +1742,8 @@ primeResponseToKE(int rcode, struct dns_msg* msg, struct trust_anchor* ta,
kkey = key_entry_create_bad(qstate->region, ta->name,
ta->namelen, ta->dclass);
else kkey = key_entry_create_null(qstate->region, ta->name,
ta->namelen, ta->dclass, NULL_KEY_TTL);
ta->namelen, ta->dclass, NULL_KEY_TTL,
*qstate->env->now);
if(!kkey) {
log_err("out of memory: allocate null prime key");
return NULL;
@ -1816,14 +1818,15 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
* there was no DS. */
*ke = key_entry_create_null(qstate->region,
qinfo->qname, qinfo->qname_len, qinfo->qclass,
ub_packed_rrset_ttl(ds));
ub_packed_rrset_ttl(ds), *qstate->env->now);
return (*ke) != NULL;
}
/* Otherwise, we return the positive response. */
log_query_info(VERB_DETAIL, "validated DS", qinfo);
*ke = key_entry_create_rrset(qstate->region,
qinfo->qname, qinfo->qname_len, qinfo->qclass, ds);
qinfo->qname, qinfo->qname_len, qinfo->qclass, ds,
*qstate->env->now);
return (*ke) != NULL;
} else if(subtype == VAL_CLASS_NODATA ||
subtype == VAL_CLASS_NAMEERROR) {
@ -1846,7 +1849,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
"referral proved no DS.");
*ke = key_entry_create_null(qstate->region,
qinfo->qname, qinfo->qname_len,
qinfo->qclass, proof_ttl);
qinfo->qclass, proof_ttl,
*qstate->env->now);
return (*ke) != NULL;
case sec_status_insecure:
verbose(VERB_DETAIL, "NSEC RRset for the "
@ -1872,7 +1876,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
"referral proved no DS.");
*ke = key_entry_create_null(qstate->region,
qinfo->qname, qinfo->qname_len,
qinfo->qclass, proof_ttl);
qinfo->qclass, proof_ttl,
*qstate->env->now);
return (*ke) != NULL;
case sec_status_indeterminate:
verbose(VERB_DETAIL, "NSEC3s for the "