mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
cleanup without losing zone contents, and also backoff for nonresponsive
masters while zone data is available. git-svn-id: file:///svn/unbound/trunk@4480 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
c834b5eecd
commit
ca60143bdf
3 changed files with 61 additions and 23 deletions
|
|
@ -695,8 +695,8 @@ daemon_cleanup(struct daemon* daemon)
|
||||||
daemon->respip_set = NULL;
|
daemon->respip_set = NULL;
|
||||||
views_delete(daemon->views);
|
views_delete(daemon->views);
|
||||||
daemon->views = NULL;
|
daemon->views = NULL;
|
||||||
auth_zones_delete(daemon->env->auth_zones);
|
if(daemon->env->auth_zones)
|
||||||
daemon->env->auth_zones = NULL;
|
auth_zones_cleanup(daemon->env->auth_zones);
|
||||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||||
daemon_remote_clear(daemon->rc);
|
daemon_remote_clear(daemon->rc);
|
||||||
for(i=0; i<daemon->num; i++)
|
for(i=0; i<daemon->num; i++)
|
||||||
|
|
@ -730,6 +730,7 @@ daemon_delete(struct daemon* daemon)
|
||||||
rrset_cache_delete(daemon->env->rrset_cache);
|
rrset_cache_delete(daemon->env->rrset_cache);
|
||||||
infra_delete(daemon->env->infra_cache);
|
infra_delete(daemon->env->infra_cache);
|
||||||
edns_known_options_delete(daemon->env);
|
edns_known_options_delete(daemon->env);
|
||||||
|
auth_zones_delete(daemon->env->auth_zones);
|
||||||
}
|
}
|
||||||
ub_randfree(daemon->rand);
|
ub_randfree(daemon->rand);
|
||||||
alloc_clear(&daemon->superalloc);
|
alloc_clear(&daemon->superalloc);
|
||||||
|
|
|
||||||
|
|
@ -5014,6 +5014,20 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||||
xfr_probe_send_or_end(xfr, env);
|
xfr_probe_send_or_end(xfr, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** disown task_nextprobe. caller must hold xfr.lock */
|
||||||
|
static void
|
||||||
|
xfr_nextprobe_disown(struct auth_xfer* xfr)
|
||||||
|
{
|
||||||
|
/* delete the timer, because the next worker to pick this up may
|
||||||
|
* not have the same event base */
|
||||||
|
comm_timer_delete(xfr->task_nextprobe->timer);
|
||||||
|
xfr->task_nextprobe->timer = NULL;
|
||||||
|
xfr->task_nextprobe->next_probe = 0;
|
||||||
|
/* we don't own this item anymore */
|
||||||
|
xfr->task_nextprobe->worker = NULL;
|
||||||
|
xfr->task_nextprobe->env = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
|
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
|
||||||
void
|
void
|
||||||
auth_xfer_timer(void* arg)
|
auth_xfer_timer(void* arg)
|
||||||
|
|
@ -5032,14 +5046,7 @@ auth_xfer_timer(void* arg)
|
||||||
lock_basic_lock(&xfr->lock);
|
lock_basic_lock(&xfr->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete the timer, because the next worker to pick this up may
|
xfr_nextprobe_disown(xfr);
|
||||||
* not have the same event base */
|
|
||||||
comm_timer_delete(xfr->task_nextprobe->timer);
|
|
||||||
xfr->task_nextprobe->timer = NULL;
|
|
||||||
xfr->task_nextprobe->next_probe = 0;
|
|
||||||
/* we don't own this item anymore */
|
|
||||||
xfr->task_nextprobe->worker = NULL;
|
|
||||||
xfr->task_nextprobe->env = NULL;
|
|
||||||
|
|
||||||
/* see if we need to start a probe (or maybe it is already in
|
/* see if we need to start a probe (or maybe it is already in
|
||||||
* progress (due to notify)) */
|
* progress (due to notify)) */
|
||||||
|
|
@ -5082,25 +5089,28 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||||
xfr->task_nextprobe->next_probe = *env->now;
|
xfr->task_nextprobe->next_probe = *env->now;
|
||||||
if(xfr->lease_time)
|
if(xfr->lease_time)
|
||||||
xfr->task_nextprobe->next_probe = xfr->lease_time;
|
xfr->task_nextprobe->next_probe = xfr->lease_time;
|
||||||
if(xfr->have_zone) {
|
|
||||||
time_t wait = xfr->refresh;
|
|
||||||
if(failure) wait = xfr->retry;
|
|
||||||
if(xfr->expiry < wait)
|
|
||||||
xfr->task_nextprobe->next_probe += xfr->expiry;
|
|
||||||
else xfr->task_nextprobe->next_probe += wait;
|
|
||||||
if(!failure) xfr->task_nextprobe->backoff = 0;
|
|
||||||
} else {
|
|
||||||
if(!failure) {
|
if(!failure) {
|
||||||
xfr->task_nextprobe->backoff = 0;
|
xfr->task_nextprobe->backoff = 0;
|
||||||
} else {
|
} else {
|
||||||
if(xfr->task_nextprobe->backoff == 0)
|
if(xfr->task_nextprobe->backoff == 0)
|
||||||
xfr->task_nextprobe->backoff = 3;
|
xfr->task_nextprobe->backoff = 3;
|
||||||
else xfr->task_nextprobe->backoff *= 2;
|
else xfr->task_nextprobe->backoff *= 2;
|
||||||
if(xfr->task_nextprobe->backoff >
|
if(xfr->task_nextprobe->backoff > AUTH_TRANSFER_MAX_BACKOFF)
|
||||||
AUTH_TRANSFER_MAX_BACKOFF)
|
|
||||||
xfr->task_nextprobe->backoff =
|
xfr->task_nextprobe->backoff =
|
||||||
AUTH_TRANSFER_MAX_BACKOFF;
|
AUTH_TRANSFER_MAX_BACKOFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(xfr->have_zone) {
|
||||||
|
time_t wait = xfr->refresh;
|
||||||
|
if(failure) wait = xfr->retry;
|
||||||
|
if(xfr->expiry < wait)
|
||||||
|
xfr->task_nextprobe->next_probe += xfr->expiry;
|
||||||
|
else xfr->task_nextprobe->next_probe += wait;
|
||||||
|
if(failure)
|
||||||
|
xfr->task_nextprobe->next_probe +=
|
||||||
|
xfr->task_nextprobe->backoff;
|
||||||
|
} else {
|
||||||
xfr->task_nextprobe->next_probe +=
|
xfr->task_nextprobe->next_probe +=
|
||||||
xfr->task_nextprobe->backoff;
|
xfr->task_nextprobe->backoff;
|
||||||
}
|
}
|
||||||
|
|
@ -5132,7 +5142,6 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||||
void
|
void
|
||||||
auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
|
auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
|
||||||
{
|
{
|
||||||
/* TODO: call this from worker0 at start of unbound */
|
|
||||||
struct auth_xfer* x;
|
struct auth_xfer* x;
|
||||||
lock_rw_wrlock(&az->lock);
|
lock_rw_wrlock(&az->lock);
|
||||||
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
|
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
|
||||||
|
|
@ -5149,6 +5158,27 @@ auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
|
||||||
lock_rw_unlock(&az->lock);
|
lock_rw_unlock(&az->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void auth_zones_cleanup(struct auth_zones* az)
|
||||||
|
{
|
||||||
|
struct auth_xfer* x;
|
||||||
|
lock_rw_wrlock(&az->lock);
|
||||||
|
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
|
||||||
|
lock_basic_lock(&x->lock);
|
||||||
|
if(x->task_nextprobe && x->task_nextprobe->worker != NULL) {
|
||||||
|
xfr_nextprobe_disown(x);
|
||||||
|
}
|
||||||
|
if(x->task_probe && x->task_probe->worker != NULL) {
|
||||||
|
xfr_probe_disown(x);
|
||||||
|
}
|
||||||
|
if(x->task_transfer && x->task_transfer->worker != NULL) {
|
||||||
|
auth_chunks_delete(x->task_transfer);
|
||||||
|
xfr_transfer_disown(x);
|
||||||
|
}
|
||||||
|
lock_basic_unlock(&x->lock);
|
||||||
|
}
|
||||||
|
lock_rw_unlock(&az->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* malloc the xfer and tasks
|
* malloc the xfer and tasks
|
||||||
* @param z: auth_zone with name of zone.
|
* @param z: auth_zone with name of zone.
|
||||||
|
|
|
||||||
|
|
@ -440,6 +440,13 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||||
*/
|
*/
|
||||||
void auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env);
|
void auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup auth zones. This removes all events from event bases.
|
||||||
|
* Stops the xfr tasks. But leaves zone data.
|
||||||
|
* @param az: auth zones structure.
|
||||||
|
*/
|
||||||
|
void auth_zones_cleanup(struct auth_zones* az);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete auth zones structure
|
* Delete auth zones structure
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue