]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
cleanup without losing zone contents, and also backoff for nonresponsive
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 31 Jan 2018 12:52:40 +0000 (12:52 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 31 Jan 2018 12:52:40 +0000 (12:52 +0000)
masters while zone data is available.

git-svn-id: file:///svn/unbound/trunk@4480 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/daemon.c
services/authzone.c
services/authzone.h

index c56581b8bc7cd5dc8274d6328a82fb4905aea738..13aba723a2a8d30bdd33586243f6a4520efcc7ac 100644 (file)
@@ -695,8 +695,8 @@ daemon_cleanup(struct daemon* daemon)
        daemon->respip_set = NULL;
        views_delete(daemon->views);
        daemon->views = NULL;
-       auth_zones_delete(daemon->env->auth_zones);
-       daemon->env->auth_zones = NULL;
+       if(daemon->env->auth_zones)
+               auth_zones_cleanup(daemon->env->auth_zones);
        /* key cache is cleared by module desetup during next daemon_fork() */
        daemon_remote_clear(daemon->rc);
        for(i=0; i<daemon->num; i++)
@@ -730,6 +730,7 @@ daemon_delete(struct daemon* daemon)
                rrset_cache_delete(daemon->env->rrset_cache);
                infra_delete(daemon->env->infra_cache);
                edns_known_options_delete(daemon->env);
+               auth_zones_delete(daemon->env->auth_zones);
        }
        ub_randfree(daemon->rand);
        alloc_clear(&daemon->superalloc);
index d3ec1e8d03c5b3c1bc0d920c1188c44b6eed21eb..b391eb24c1e7743637f25614c6a4aec62539b01a 100644 (file)
@@ -5014,6 +5014,20 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
        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 */
 void
 auth_xfer_timer(void* arg)
@@ -5032,14 +5046,7 @@ auth_xfer_timer(void* arg)
                lock_basic_lock(&xfr->lock);
        }
 
-       /* 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;
+       xfr_nextprobe_disown(xfr);
 
        /* see if we need to start a probe (or maybe it is already in
         * 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;
        if(xfr->lease_time)
                xfr->task_nextprobe->next_probe = xfr->lease_time;
+       
+       if(!failure) {
+               xfr->task_nextprobe->backoff = 0;
+       } else {
+               if(xfr->task_nextprobe->backoff == 0)
+                               xfr->task_nextprobe->backoff = 3;
+               else    xfr->task_nextprobe->backoff *= 2;
+               if(xfr->task_nextprobe->backoff > AUTH_TRANSFER_MAX_BACKOFF)
+                       xfr->task_nextprobe->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->backoff = 0;
+               if(failure)
+                       xfr->task_nextprobe->next_probe +=
+                               xfr->task_nextprobe->backoff;
        } else {
-               if(!failure) {
-                       xfr->task_nextprobe->backoff = 0;
-               } else {
-                       if(xfr->task_nextprobe->backoff == 0)
-                               xfr->task_nextprobe->backoff = 3;
-                       else    xfr->task_nextprobe->backoff *= 2;
-                       if(xfr->task_nextprobe->backoff >
-                               AUTH_TRANSFER_MAX_BACKOFF)
-                               xfr->task_nextprobe->backoff =
-                                       AUTH_TRANSFER_MAX_BACKOFF;
-               }
                xfr->task_nextprobe->next_probe +=
                        xfr->task_nextprobe->backoff;
        }
@@ -5132,7 +5142,6 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
 void
 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;
        lock_rw_wrlock(&az->lock);
        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);
 }
 
+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
  * @param z: auth_zone with name of zone.
index 93989cd2d7f52bbaa5846658459140a399b44c80..2b1766696d2b99f3b5764d54d2129df9082516cd 100644 (file)
@@ -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);
 
+/**
+ * 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
  */