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);