Commit e9a95cf0dc for bind

commit e9a95cf0dc3b160a486fb70c2a68372ffe2a981a
Author: Aram Sargsyan <aram@isc.org>
Date:   Thu Oct 8 13:19:55 2026 +0000

    Use the clockskew value to derive the duplicate list's entries lifetime

    The control channel keeps a list of recent messages to check against
    in order to suppress duplicates. DUP_LIFETIME is the lifetime of
    the items in the hashtable after which they get cleaned up, and is
    set to 900 seconds.

    The controlconf.c:control_recvmessage() function doesn't allow messages
    which are more than CLOCKSKEW seconds behind or ahead anyway, so
    capping the lifetime of the list's entries to the double amount of
    the clock skew's value instead having a seprate definition makes sense,
    which is implemented now.

    Also, instead of keeping the current time ('now') in the duplicate
    entries list, keep the expire time, so that cleanup functions does
    not need to know the clock skew value from another module, it just
    compares the expire time with the current time.

    Co-authored-by: Mark Andrews <marka@isc.org>

diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c
index bd1c4a99d3..8051581669 100644
--- a/bin/named/controlconf.c
+++ b/bin/named/controlconf.c
@@ -148,7 +148,12 @@ ISC_REFCOUNT_DECL(controllistener);
 ISC_REFCOUNT_DECL(controlconnection);
 #endif

-#define CLOCKSKEW 300
+/*
+ * The tolerated clock skew (in seconds) for the incoming control channel
+ * commands. Also, the double amount of this value is used as a lifetime for
+ * the items in the duplicate commands list before they get cleaned up.
+ */
+constexpr uint32_t cc_clockskew = 300;

 static void
 free_controlkey(controlkey_t *key, isc_mem_t *mctx) {
@@ -459,8 +464,8 @@ control_recvmessage(isc_nmhandle_t *handle ISC_ATTR_UNUSED, isc_result_t result,
 	}

 	if (isccc_cc_lookupuint32(conn->ctrl, "_tim", &sent) == ISC_R_SUCCESS) {
-		if ((sent + CLOCKSKEW) < conn->now ||
-		    (sent - CLOCKSKEW) > conn->now)
+		if (sent + cc_clockskew < conn->now ||
+		    sent - cc_clockskew > conn->now)
 		{
 			CLEANUP(DNS_R_CLOCKSKEW);
 		}
@@ -486,7 +491,7 @@ control_recvmessage(isc_nmhandle_t *handle ISC_ATTR_UNUSED, isc_result_t result,
 		listener->controls->last_cleanup_time = conn->now;
 	}
 	result = isccc_cc_checkdup(listener->controls->symtab, conn->request,
-				   conn->now);
+				   conn->now + 2 * cc_clockskew + 1);
 	UNLOCK(&listener->controls->symtab_lock);
 	if (result != ISC_R_SUCCESS) {
 		if (result == ISC_R_EXISTS) {
diff --git a/lib/isc/include/isc/symtab.h b/lib/isc/include/isc/symtab.h
index 514cec3f66..375039c2b4 100644
--- a/lib/isc/include/isc/symtab.h
+++ b/lib/isc/include/isc/symtab.h
@@ -112,7 +112,7 @@ isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type,
  * \li	'found' is either NULL or a pointer to isc_symvalue_t
  *
  * Returns:
- * \li	#ISC_R_SUCCESS	Symbol has been deleted from the symbol table
+ * \li	#ISC_R_SUCCESS	Symbol has been found in the symbol table
  * \li	#ISC_R_NOTFOUND	Symbol not found in the symbol table
  *
  * Note:
diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c
index f9baf88032..7b9462c3e7 100644
--- a/lib/isccc/cc.c
+++ b/lib/isccc/cc.c
@@ -50,8 +50,7 @@
 #include <isccc/symtype.h>
 #include <isccc/util.h>

-#define MAX_TAGS     256
-#define DUP_LIFETIME 900
+#define MAX_TAGS 256
 #ifndef ISCCC_MAXDEPTH
 #define ISCCC_MAXDEPTH \
 	10 /* Big enough for rndc which just sends a string each way. */
@@ -911,20 +910,15 @@ symtab_undefine(char *key, unsigned int type, isc_symvalue_t value, void *arg) {

 static bool
 symtab_clean(char *key, unsigned int type, isc_symvalue_t value, void *arg) {
-	isccc_time_t *now;
+	isccc_time_t *now = arg;

 	UNUSED(key);
 	UNUSED(type);

-	now = arg;
-
-	if (*now < value.as_uinteger) {
-		return false;
-	}
-	if ((*now - value.as_uinteger) < DUP_LIFETIME) {
-		return false;
+	if (value.as_uinteger <= *now) {
+		return true;
 	}
-	return true;
+	return false;
 }

 void
@@ -954,7 +948,7 @@ has_whitespace(const char *str) {

 isc_result_t
 isccc_cc_checkdup(isc_symtab_t *symtab, isccc_sexpr_t *message,
-		  isccc_time_t now) {
+		  isccc_time_t expire) {
 	const char *_frm;
 	const char *_to;
 	char *_ser = NULL, *_tim = NULL, *tmp;
@@ -1007,7 +1001,7 @@ isccc_cc_checkdup(isc_symtab_t *symtab, isccc_sexpr_t *message,
 		return ISC_R_NOMEMORY;
 	}
 	snprintf(key, len, "%s;%s;%s;%s", _frm, _to, _ser, _tim);
-	value.as_uinteger = now;
+	value.as_uinteger = expire;
 	result = isc_symtab_define(symtab, key, ISCCC_SYMTYPE_CCDUP, value,
 				   isc_symexists_reject);
 	if (result != ISC_R_SUCCESS) {
diff --git a/lib/isccc/include/isccc/cc.h b/lib/isccc/include/isccc/cc.h
index 0e257bde95..7371e0c781 100644
--- a/lib/isccc/include/isccc/cc.h
+++ b/lib/isccc/include/isccc/cc.h
@@ -122,7 +122,9 @@ isccc_cc_createsymtab(isc_mem_t *mctx, isc_symtab_t **symtabp);
 void
 isccc_cc_cleansymtab(isc_symtab_t *symtab, isccc_time_t now);

-/*% Check for Duplicates */
+/*%
+ * Check for Duplicate.  Entries are not removed before expire is reached.
+ */
 isc_result_t
 isccc_cc_checkdup(isc_symtab_t *symtab, isccc_sexpr_t *message,
-		  isccc_time_t now);
+		  isccc_time_t expire);