From 0f5a761993c2f5f24f42693a86919a1afdcff671 Mon Sep 17 00:00:00 2001
From: Marek Vavrusa <marek.vavrusa@nic.cz>
Date: Wed, 8 Aug 2012 12:32:19 +0200
Subject: [PATCH] Updated unguarded places and zone lookup from qname.

refs #1976
---
 src/knot/server/xfr-handler.c        |  4 +++-
 src/libknot/nameserver/name-server.c | 11 ++++-------
 src/libknot/nameserver/name-server.h |  5 ++++-
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c
index f52ea779ef..01ce1bc205 100644
--- a/src/knot/server/xfr-handler.c
+++ b/src/knot/server/xfr-handler.c
@@ -704,6 +704,7 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf,
 			
 			/* AXFR bootstrap timeout. */
 			rcu_read_lock();
+			/*! \todo #1976 Do not reschedule if zone is being discarded. */
 			if (ret != KNOTD_EOK && !knot_zone_contents(zone)) {
 				/* Schedule request (60 - 90s random delay). */
 				int tmr_s = AXFR_BOOTSTRAP_RETRY;
@@ -784,6 +785,7 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
 			strerror_r(errno, ebuf, sizeof(ebuf));
 			dbg_xfr("xfr: couldn't write request to evqueue: %s\n",
 			        ebuf);
+			rcu_read_unlock();
 			return KNOTD_ERROR;
 		}
 		return KNOTD_EOK;
@@ -1002,6 +1004,7 @@ static int xfr_update_msgpref(knot_ns_xfr_t *req, const char *keytag)
 		return KNOTD_EINVAL;
 	}
 
+	conf_read_lock();
 	char r_addr[SOCKADDR_STRLEN];
 	char *r_key = NULL;
 	int r_port = sockaddr_portnum(&req->addr);
@@ -1028,7 +1031,6 @@ static int xfr_update_msgpref(knot_ns_xfr_t *req, const char *keytag)
 	}
 
 	/* Prepare log message. */
-	conf_read_lock();
 	const char *zname = req->zname;
 	if (zname == NULL && req->zone != NULL) {
 		zonedata_t *zd = (zonedata_t *)knot_zone_data(req->zone);
diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index 134fa8a659..4c963f665f 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -3974,9 +3974,7 @@ dbg_ns_exec_verb(
 }
 
 /*----------------------------------------------------------------------------*/
-/*! \todo In this function, xfr->zone is properly set. If this is so, we do not
- *        have to search for the zone after the transfer has finished.
- */
+
 int knot_ns_process_ixfrin(knot_nameserver_t *nameserver, 
                              knot_ns_xfr_t *xfr)
 {
@@ -4008,9 +4006,9 @@ int knot_ns_process_ixfrin(knot_nameserver_t *nameserver,
 		}
 
 		// find zone associated with the changesets
-		knot_zone_t *zone = knot_zonedb_find_zone(
-		                 nameserver->zone_db,
-		                 knot_rrset_owner(chgsets->first_soa));
+		/* Must not search for the zone in zonedb as it may fetch a
+		 * different zone than the one the transfer started on. */
+		knot_zone_t *zone = xfr->zone;
 		if (zone == NULL) {
 			dbg_ns("No zone found for incoming IXFR!\n");
 			knot_free_changesets(
@@ -4020,7 +4018,6 @@ int knot_ns_process_ixfrin(knot_nameserver_t *nameserver,
 		
 		switch (ret) {
 		case XFRIN_RES_COMPLETE:
-			xfr->zone = zone;
 			break;
 		case XFRIN_RES_SOA_ONLY: {
 			// compare the SERIAL from the changeset with the zone's
diff --git a/src/libknot/nameserver/name-server.h b/src/libknot/nameserver/name-server.h
index b728e66abe..9c6aa4146d 100644
--- a/src/libknot/nameserver/name-server.h
+++ b/src/libknot/nameserver/name-server.h
@@ -304,11 +304,14 @@ int knot_ns_answer_ixfr(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr);
  * \param nameserver Name server structure to provide the data for answering.
  * \param xfr Persistent transfer-specific data.
  *
- * \todo Document me.
  */
 int knot_ns_process_axfrin(knot_nameserver_t *nameserver, 
                              knot_ns_xfr_t *xfr);
 
+/*! \todo Document me.
+ *  \todo #1976 Must not lookup zone from zonedb as it may be different than the
+ *        the one on which the transfer was carried out.
+ */
 int knot_ns_switch_zone(knot_nameserver_t *nameserver, 
                           knot_ns_xfr_t *xfr);
 
-- 
GitLab