From ffeda92cd85461dad3bea74dd4892ef990fec4c9 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Wed, 30 Nov 2022 18:40:27 +1100
Subject: [PATCH] Suppress duplicate dns_db_updatenotify_register registrations

Duplicate dns_db_updatenotify_register registrations need to be
suppressed to ensure that dns_db_updatenotify_unregister is successful.

(cherry picked from commit f13e71e55167bf9c94f4faf1dab110467158e7b4)
---
 lib/dns/catz.c           |  6 +++---
 lib/dns/db.c             | 12 +++++++++++-
 lib/dns/include/dns/db.h |  2 +-
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/lib/dns/catz.c b/lib/dns/catz.c
index 487d20833e1..332f9877360 100644
--- a/lib/dns/catz.c
+++ b/lib/dns/catz.c
@@ -810,9 +810,9 @@ dns_catz_zone_detach(dns_catz_zone_t **zonep) {
 		zone->magic = 0;
 		isc_timer_detach(&zone->updatetimer);
 		if (zone->db_registered) {
-			INSIST(dns_db_updatenotify_unregister(
-				       zone->db, dns_catz_dbupdate_callback,
-				       zone->catzs) == ISC_R_SUCCESS);
+			dns_db_updatenotify_unregister(
+				zone->db, dns_catz_dbupdate_callback,
+				zone->catzs);
 		}
 		if (zone->dbversion) {
 			dns_db_closeversion(zone->db, &zone->dbversion, false);
diff --git a/lib/dns/db.c b/lib/dns/db.c
index c5de3d9e0b0..04cf6560fea 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1013,7 +1013,7 @@ dns_db_rpz_ready(dns_db_t *db) {
 	return ((db->methods->rpz_ready)(db));
 }
 
-/**
+/*
  * Attach a notify-on-update function the database
  */
 isc_result_t
@@ -1024,6 +1024,16 @@ dns_db_updatenotify_register(dns_db_t *db, dns_dbupdate_callback_t fn,
 	REQUIRE(db != NULL);
 	REQUIRE(fn != NULL);
 
+	for (listener = ISC_LIST_HEAD(db->update_listeners); listener != NULL;
+	     listener = ISC_LIST_NEXT(listener, link))
+	{
+		if ((listener->onupdate == fn) &&
+		    (listener->onupdate_arg == fn_arg))
+		{
+			return (ISC_R_SUCCESS);
+		}
+	}
+
 	listener = isc_mem_get(db->mctx, sizeof(dns_dbonupdatelistener_t));
 
 	listener->onupdate = fn;
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index f14d9f6c529..08bdc80e4ee 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -1673,11 +1673,11 @@ dns_db_updatenotify_register(dns_db_t *db, dns_dbupdate_callback_t fn,
 			     void *fn_arg);
 /*%<
  * Register a notify-on-update callback function to a database.
+ * Duplicate callbacks are suppressed.
  *
  * Requires:
  *
  * \li	'db' is a valid database
- * \li	'db' does not have an update callback registered
  * \li	'fn' is not NULL
  *
  */
-- 
2.23.0