- Fix #1253: Cache entries fail to be removed from Redis cachedb

backend with unbound-control flush* +c.
This commit is contained in:
W.C.A. Wijngaards 2025-03-21 12:56:21 +01:00
parent eccf52e39d
commit a42fb99508
2 changed files with 28 additions and 15 deletions

View file

@ -61,7 +61,7 @@ struct redis_moddata {
struct timeval command_timeout; /* timeout for commands */
struct timeval connect_timeout; /* timeout for connect */
int logical_db; /* the redis logical database to use */
int setex_available; /* if the SETEX command is supported */
int set_with_ex_available; /* if the SET with EX command is supported */
};
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
@ -195,12 +195,12 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
moddata->ctxs[env->alloc->thread_num] != NULL) {
redisReply* rep = NULL;
int redis_reply_type = 0;
/** check if setex command is supported */
/** check if set with ex command is supported */
rep = redis_command(env, cachedb_env,
"SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0);
"SET __UNBOUND_REDIS_CHECK__ none EX 1", NULL, 0);
if(!rep) {
/** init failed, no response from redis server*/
goto setex_fail;
goto set_with_ex_fail;
}
redis_reply_type = rep->type;
freeReplyObject(rep);
@ -208,17 +208,17 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
case REDIS_REPLY_STATUS:
break;
default:
/** init failed, setex command not supported */
goto setex_fail;
/** init failed, set_with_ex command not supported */
goto set_with_ex_fail;
}
moddata->setex_available = 1;
moddata->set_with_ex_available = 1;
}
return 1;
setex_fail:
set_with_ex_fail:
log_err("redis_init: failure during redis_init, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
"redis-expire-records option requires the SET with EX command "
"(redis >= 2.6.2)");
return 1;
fail:
moddata_clean(&moddata);
@ -352,12 +352,14 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
int n;
struct redis_moddata* moddata = (struct redis_moddata*)
cachedb_env->backend_data;
int set_ttl = (moddata->setex_available &&
int set_ttl = (moddata->set_with_ex_available &&
env->cfg->redis_expire_records &&
(!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
/* Supported commands:
* - "SET " + key + " %b"
* - "SETEX " + key + " " + ttl + " %b"
* - "SET " + key + " %b EX " + ttl
* older redis 2.0.0 was "SETEX " + key + " " + ttl + " %b"
* - "EXPIRE " + key + " 0"
*/
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1];
@ -365,14 +367,21 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
} else if(ttl == 0) {
/* use the EXPIRE command, SET with EX 0 is an invalid time. */
verbose(VERB_ALGO, "redis_store expire %s (%d bytes)",
key, (int)data_len);
n = snprintf(cmdbuf, sizeof(cmdbuf), "EXPIRE %s 0", key);
data = NULL;
data_len = 0;
} else {
/* add expired ttl time to redis ttl to avoid premature eviction of key */
ttl += env->cfg->serve_expired_ttl;
verbose(VERB_ALGO, "redis_store %s (%d bytes) with ttl %u",
key, (int)data_len, (uint32_t)ttl);
key, (int)data_len, (unsigned)(uint32_t)ttl);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key,
(uint32_t)ttl);
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b EX %u", key,
(unsigned)(uint32_t)ttl);
}

View file

@ -1,3 +1,7 @@
21 March 2025: Wouter
- Fix #1253: Cache entries fail to be removed from Redis cachedb
backend with unbound-control flush* +c.
20 March 2025: Wouter
- Fix print of RR type NSAP-PTR, it is an unquoted string.