From 9af6a86ecfd99c2362dabe0929810265eaf8e427 Mon Sep 17 00:00:00 2001
From: Jan Kadlec <jan.kadlec@nic.cz>
Date: Thu, 24 Apr 2014 13:23:27 +0200
Subject: [PATCH] ttl-check: Better TTL error handling, no bool params in API.

---
 src/knot/dnssec/nsec3-chain.c |  4 +--
 src/knot/updates/xfr-in.c     | 15 +++++------
 src/knot/zone/node.c          | 15 +++++------
 src/knot/zone/node.h          |  4 +--
 src/knot/zone/zone-contents.c |  8 +++---
 src/knot/zone/zone-contents.h |  2 +-
 src/knot/zone/zone-create.c   | 47 +++++++++++++++--------------------
 src/knot/zone/zone-create.h   |  6 +----
 tests/process_query.c         |  2 +-
 9 files changed, 46 insertions(+), 57 deletions(-)

diff --git a/src/knot/dnssec/nsec3-chain.c b/src/knot/dnssec/nsec3-chain.c
index 41a4cff6d..c3e8f52bc 100644
--- a/src/knot/dnssec/nsec3-chain.c
+++ b/src/knot/dnssec/nsec3-chain.c
@@ -121,7 +121,7 @@ static int shallow_copy_signature(const zone_node_t *from, zone_node_t *to)
 	if (knot_rrset_empty(&from_sig)) {
 		return KNOT_EOK;
 	}
-	return node_add_rrset(to, &from_sig, NULL);
+	return node_add_rrset(to, &from_sig);
 }
 
 /*!
@@ -298,7 +298,7 @@ static zone_node_t *create_nsec3_node(knot_dname_t *owner,
 		return NULL;
 	}
 
-	ret = node_add_rrset(new_node, &nsec3_rrset, NULL);
+	ret = node_add_rrset(new_node, &nsec3_rrset);
 	knot_rrset_clear(&nsec3_rrset, NULL);
 	if (ret != KNOT_EOK) {
 		node_free(&new_node);
diff --git a/src/knot/updates/xfr-in.c b/src/knot/updates/xfr-in.c
index bd8058ed9..5e5e493c6 100644
--- a/src/knot/updates/xfr-in.c
+++ b/src/knot/updates/xfr-in.c
@@ -845,14 +845,15 @@ static int add_rr(zone_node_t *node, const knot_rrset_t *rr,
 		}
 	}
 	// Insert new RR to RRSet, data will be copied.
-	bool ttl_err = false;
-	int ret = node_add_rrset(node, rr, &ttl_err);
+	int ret = node_add_rrset(node, rr);
 	if (ret != KNOT_EOK) {
-		return ret;
-	}
-	if (ttl_err) {
-		ret = log_ttl_error(node, rr, master);
-		if (ret != KNOT_EOK) {
+		if (ret == KNOT_ETTL) {
+			log_ttl_error(node, rr);
+			if (master) {
+				// TTL errors fatal on master.
+				return KNOT_ETTL;
+			}
+		} else {
 			return ret;
 		}
 	}
diff --git a/src/knot/zone/node.c b/src/knot/zone/node.c
index 5c0b3c256..c7a8db120 100644
--- a/src/knot/zone/node.c
+++ b/src/knot/zone/node.c
@@ -164,7 +164,7 @@ zone_node_t *node_shallow_copy(const zone_node_t *src)
 	return dst;
 }
 
-int node_add_rrset(zone_node_t *node, const knot_rrset_t *rrset,  bool *ttl_err)
+int node_add_rrset(zone_node_t *node, const knot_rrset_t *rrset)
 {
 	if (node == NULL || rrset == NULL) {
 		return KNOT_EINVAL;
@@ -173,13 +173,14 @@ int node_add_rrset(zone_node_t *node, const knot_rrset_t *rrset,  bool *ttl_err)
 	for (uint16_t i = 0; i < node->rrset_count; ++i) {
 		if (node->rrs[i].type == rrset->type) {
 			struct rr_data *node_data = &node->rrs[i];
-			if (ttl_err) {
-				// Do TTL check.
-				*ttl_err = ttl_error(node_data, rrset);
+			const bool ttl_err = ttl_error(node_data, rrset);
+			int ret = knot_rdataset_merge(&node_data->rrs,
+			                              &rrset->rrs, NULL);
+			if (ret != KNOT_EOK) {
+				return ret;
+			} else {
+				return ttl_err ? KNOT_ETTL : KNOT_EOK;
 			}
-
-			return knot_rdataset_merge(&node_data->rrs,
-			                           &rrset->rrs, NULL);
 		}
 	}
 
diff --git a/src/knot/zone/node.h b/src/knot/zone/node.h
index 65e4ff226..e49f88048 100644
--- a/src/knot/zone/node.h
+++ b/src/knot/zone/node.h
@@ -126,12 +126,10 @@ zone_node_t *node_shallow_copy(const zone_node_t *src);
  *
  * \param node     Node to add the RRSet to.
  * \param rrset    RRSet to add.
- * \param ttl_err  Set to true if TTL error occured when inserting. New zone API
- *                 will obsolete this parameter.
  *
  * \return KNOT_E*
  */
-int node_add_rrset(zone_node_t *node, const knot_rrset_t *rrset, bool *ttl_err);
+int node_add_rrset(zone_node_t *node, const knot_rrset_t *rrset);
 
 /*!
  * \brief Removes data for given RR type from node.
diff --git a/src/knot/zone/zone-contents.c b/src/knot/zone/zone-contents.c
index 7129c1ea9..c6bf11249 100644
--- a/src/knot/zone/zone-contents.c
+++ b/src/knot/zone/zone-contents.c
@@ -644,7 +644,7 @@ static zone_node_t *knot_zone_contents_get_nsec3_node(
 
 static int insert_rr(knot_zone_contents_t *z,
                      const knot_rrset_t *rr, zone_node_t **n,
-                     bool nsec3, bool *ttl_err)
+                     bool nsec3)
 {
 	if (z == NULL || knot_rrset_empty(rr) || n == NULL) {
 		return KNOT_EINVAL;
@@ -674,7 +674,7 @@ static int insert_rr(knot_zone_contents_t *z,
 		}
 	}
 
-	return node_add_rrset(*n, rr, ttl_err);
+	return node_add_rrset(*n, rr);
 }
 
 static int recreate_normal_tree(const knot_zone_contents_t *z,
@@ -779,9 +779,9 @@ static bool rrset_is_nsec3rel(const knot_rrset_t *rr)
 }
 
 int knot_zone_contents_add_rr(knot_zone_contents_t *z,
-                              const knot_rrset_t *rr, zone_node_t **n, bool *ttl_err)
+                              const knot_rrset_t *rr, zone_node_t **n)
 {
-	return insert_rr(z, rr, n, rrset_is_nsec3rel(rr), ttl_err);
+	return insert_rr(z, rr, n, rrset_is_nsec3rel(rr));
 }
 
 /*----------------------------------------------------------------------------*/
diff --git a/src/knot/zone/zone-contents.h b/src/knot/zone/zone-contents.h
index d8b1716bf..9eeac9a6b 100644
--- a/src/knot/zone/zone-contents.h
+++ b/src/knot/zone/zone-contents.h
@@ -93,7 +93,7 @@ void knot_zone_contents_set_gen_old(knot_zone_contents_t *contents);
 void knot_zone_contents_set_gen_new(knot_zone_contents_t *contents);
 
 int knot_zone_contents_add_rr(knot_zone_contents_t *z,
-                              const knot_rrset_t *rr, zone_node_t **n, bool *ttl_err);
+                              const knot_rrset_t *rr, zone_node_t **n);
 
 int knot_zone_contents_remove_node(knot_zone_contents_t *contents,
 	const knot_dname_t *owner);
diff --git a/src/knot/zone/zone-create.c b/src/knot/zone/zone-create.c
index 5e339e7cb..0f9288601 100644
--- a/src/knot/zone/zone-create.c
+++ b/src/knot/zone/zone-create.c
@@ -55,9 +55,8 @@ static int add_rdata_to_rr(knot_rrset_t *rrset, const zs_scanner_t *scanner)
 	                         scanner->r_ttl, NULL);
 }
 
-static bool handle_err(zcreator_t *zc,
-                       const knot_rrset_t *rr,
-                       int ret)
+static bool handle_err(zcreator_t *zc, const zone_node_t *node,
+                       const knot_rrset_t *rr, int ret, bool master)
 {
 	char *zname = zc->z ? knot_dname_to_str(zc->z->apex->owner) : NULL;
 	char *rrname = rr ? knot_dname_to_str(rr->owner) : NULL;
@@ -67,6 +66,13 @@ static bool handle_err(zcreator_t *zc,
 		free(zname);
 		free(rrname);
 		return true;
+	} else if (ret == KNOT_ETTL) {
+		free(zname);
+		free(rrname);
+		assert(node);
+		log_ttl_error(node, rr);
+		// Fail if we're the master for this zone.
+		return !master;
 	} else {
 		log_zone_error("Zone %s: Cannot process record %s, stopping.\n",
 		               zname ? zname : "unknown", rrname ? rrname : "unknown");
@@ -76,7 +82,7 @@ static bool handle_err(zcreator_t *zc,
 	}
 }
 
-int log_ttl_error(const zone_node_t *node, const knot_rrset_t *rr, bool master)
+void log_ttl_error(const zone_node_t *node, const knot_rrset_t *rr)
 {
 	err_handler_t err_handler;
 	err_handler_init(&err_handler);
@@ -90,16 +96,9 @@ int log_ttl_error(const zone_node_t *node, const knot_rrset_t *rr, bool master)
 		*info_str = '\0';
 	}
 
-	if (master) {
-		/*!< \todo REPLACE WITH FATAL ERROR */
-		err_handler_handle_error(&err_handler, node,
-		                         ZC_ERR_TTL_MISMATCH, info_str);
-		return KNOT_ETTL;
-	} else {
-		err_handler_handle_error(&err_handler, node,
-		                         ZC_ERR_TTL_MISMATCH, info_str);
-		return KNOT_EOK;
-	}
+	/*!< \todo REPLACE WITH FATAL ERROR for master. */
+	err_handler_handle_error(&err_handler, node,
+	                         ZC_ERR_TTL_MISMATCH, info_str);
 }
 
 int zcreator_step(zcreator_t *zc, const knot_rrset_t *rr)
@@ -114,25 +113,19 @@ int zcreator_step(zcreator_t *zc, const knot_rrset_t *rr)
 		return KNOT_EOK;
 	}
 
-	bool ttl_err = false;
 	zone_node_t *node = NULL;
-	int ret = knot_zone_contents_add_rr(zc->z, rr, &node, &ttl_err);
-	if (ret < 0) {
-		if (!handle_err(zc, rr, ret)) {
+	int ret = knot_zone_contents_add_rr(zc->z, rr, &node);
+	if (ret != KNOT_EOK) {
+		if (!handle_err(zc, node, rr, ret, zc->master)) {
 			// Fatal error
 			return ret;
 		}
-		// Recoverable error, skip record
-		return KNOT_EOK;
-	}
-	assert(node);
-
-	if (ttl_err) {
-		ret = log_ttl_error(node, rr, zc->master);
-		if (ret != KNOT_EOK) {
-			return ret;
+		if (ret == KNOT_EOUTOFZONE) {
+			// Skip out-of-zone record
+			return KNOT_EOK;
 		}
 	}
+	assert(node);
 
 	// Do node semantic checks
 	err_handler_t err_handler;
diff --git a/src/knot/zone/zone-create.h b/src/knot/zone/zone-create.h
index 051b04658..92e26c3de 100644
--- a/src/knot/zone/zone-create.h
+++ b/src/knot/zone/zone-create.h
@@ -103,12 +103,8 @@ void process_error(zs_scanner_t *scanner);
  *
  * \param node    Node with TTL mismatch.
  * \param rr      RR that caused the mismatch.
- * \param master  Master/slave switch.
- *
- * \retval KNOT_EOK if slave.
- * \retval KNOT_ETTL if master.
  */
-int log_ttl_error(const zone_node_t *node, const knot_rrset_t *rr, bool master);
+void log_ttl_error(const zone_node_t *node, const knot_rrset_t *rr);
 
 #endif /* _KNOTD_ZONELOAD_H_ */
 
diff --git a/tests/process_query.c b/tests/process_query.c
index e94abd07d..f0b4d76e9 100644
--- a/tests/process_query.c
+++ b/tests/process_query.c
@@ -52,7 +52,7 @@ void create_root_zone(server_t *server, mm_ctx_t *mm)
 	                                         KNOT_RRTYPE_SOA, KNOT_CLASS_IN,
 	                                         NULL);
 	knot_rrset_add_rdata(soa_rrset, SOA_RDATA, SOA_RDLEN, 7200, NULL);
-	node_add_rrset(root->contents->apex, soa_rrset, NULL);
+	node_add_rrset(root->contents->apex, soa_rrset);
 
 	/* Bake the zone. */
 	zone_node_t *first_nsec3 = NULL, *last_nsec3 = NULL;
-- 
GitLab