From 111edec7bd27fe911a0a94612c989a2e045c37a8 Mon Sep 17 00:00:00 2001 From: Marek Vavrusa <marek.vavrusa@nic.cz> Date: Mon, 24 Jun 2013 17:58:46 +0200 Subject: [PATCH] Update timers only after 'reloading' state finishes. This caused a bug when a SOA query answer was received before reloading was complete, so the zone wasn't visible in the zone database yet. --- src/knot/server/xfr-handler.c | 2 +- src/knot/server/zones.c | 49 +++++++++++++++++++++-------------- src/knot/server/zones.h | 3 ++- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c index 0cc13ec18a..c7c1abfcca 100644 --- a/src/knot/server/xfr-handler.c +++ b/src/knot/server/xfr-handler.c @@ -763,7 +763,7 @@ static int xfr_task_xfer(xfrworker_t *w, knot_ns_xfr_t *rq) } /* Update REFRESH/RETRY */ - zones_schedule_refresh(rq->zone); + zones_schedule_refresh(rq->zone, 0); ret = KNOT_ECONNREFUSED; /* Disconnect */ } diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 46ba65ea38..d5fd049477 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -1188,24 +1188,12 @@ static int zones_insert_zone(conf_zone_t *z, knot_zone_t **dst, z->name, knot_strerror(ar)); } - - /* Update events scheduled for zone. */ - evsched_t *sch = ((server_t *)knot_ns_get_data(ns))->sched; - zones_schedule_refresh(zone); - zones_schedule_notify(zone); - - /* Refresh new slave zones (almost) immediately. */ - if(is_new && zd->xfr_in.timer) { - evsched_cancel(sch, zd->xfr_in.timer); - evsched_schedule(sch, zd->xfr_in.timer, - zd->xfr_in.bootstrap_retry / 2); - } - /* Schedule IXFR database syncing. */ /*! \note This has to remain separate as it must not be * triggered by a zone update or SOA response. */ /* Fetch zone data. */ + evsched_t *sch = ((server_t *)knot_ns_get_data(ns))->sched; int sync_tmr = z->dbsync_timeout * 1000; /* s -> ms. */ if (zd->ixfr_dbsync != NULL) { evsched_cancel(sch, zd->ixfr_dbsync); @@ -2515,7 +2503,7 @@ int zones_process_response(knot_nameserver_t *nameserver, /* No updates available. */ if (ret == 0) { - zones_schedule_refresh(zone); + zones_schedule_refresh(zone, 0); rcu_read_unlock(); return KNOT_EUPTODATE; } @@ -2709,6 +2697,25 @@ int zones_ns_conf_hook(const struct conf_t *conf, void *data) /* Delete all deprecated zones and delete the old database. */ knot_zonedb_deep_free(&old_db); + /* Update events scheduled for zone. */ + rcu_read_lock(); + knot_zone_t **zones = (knot_zone_t **)knot_zonedb_zones(ns->zone_db); + if (zones == NULL) { + rcu_read_unlock(); + return KNOT_ENOMEM; + } + + /* REFRESH zones. */ + for (unsigned i = 0; i < knot_zonedb_zone_count(ns->zone_db); ++i) { + /* Refresh new slave zones (almost) immediately. */ + zones_schedule_refresh(zones[i], tls_rand() * 500 + i/2); + zones_schedule_notify(zones[i]); + } + + /* Unlock RCU. */ + rcu_read_unlock(); + free(zones); + return KNOT_EOK; } @@ -3179,7 +3186,7 @@ int zones_schedule_notify(knot_zone_t *zone) return KNOT_EOK; } -int zones_schedule_refresh(knot_zone_t *zone) +int zones_schedule_refresh(knot_zone_t *zone, unsigned time) { if (!zone || !zone->data) { return KNOT_EINVAL; @@ -3208,11 +3215,13 @@ int zones_schedule_refresh(knot_zone_t *zone) if (zd->xfr_in.has_master) { /* Schedule REFRESH timer. */ - uint32_t refresh_tmr = 0; - if (knot_zone_contents(zone)) { - refresh_tmr = zones_jitter(zones_soa_refresh(zone)); - } else { - refresh_tmr = zd->xfr_in.bootstrap_retry; + uint32_t refresh_tmr = time; + if (refresh_tmr == 0) { + if (knot_zone_contents(zone)) { + refresh_tmr = zones_jitter(zones_soa_refresh(zone)); + } else { + refresh_tmr = zd->xfr_in.bootstrap_retry; + } } zd->xfr_in.timer = evsched_schedule_cb(sch, zones_refresh_ev, zone, refresh_tmr); diff --git a/src/knot/server/zones.h b/src/knot/server/zones.h index 26880bf274..5045d50bd2 100644 --- a/src/knot/server/zones.h +++ b/src/knot/server/zones.h @@ -302,12 +302,13 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs, * REFRESH/RETRY/EXPIRE timers are updated according to SOA. * * \param zone Related zone. + * \param time Specific time or 0 for default. * * \retval KNOT_EOK * \retval KNOT_EINVAL * \retval KNOT_ERROR */ -int zones_schedule_refresh(knot_zone_t *zone); +int zones_schedule_refresh(knot_zone_t *zone, unsigned time); /*! * \brief Schedule NOTIFY after zone update. -- GitLab