Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Talkabout/unbound into Ta…
Browse files Browse the repository at this point in the history
…lkabout-redis-expire-records
  • Loading branch information
gthess committed Apr 1, 2020
2 parents 65e7be5 + e7b4529 commit 20aa782
Show file tree
Hide file tree
Showing 11 changed files with 3,282 additions and 3,182 deletions.
5 changes: 3 additions & 2 deletions cachedb/cachedb.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ testframe_lookup(struct module_env* env, struct cachedb_env* cachedb_env,

static void
testframe_store(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, uint8_t* data, size_t data_len)
char* key, uint8_t* data, size_t data_len, time_t ATTR_UNUSED(ttl))
{
struct testframe_moddata* d = (struct testframe_moddata*)
cachedb_env->backend_data;
Expand Down Expand Up @@ -606,7 +606,8 @@ cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
/* call backend */
(*ie->backend->store)(qstate->env, ie, key,
sldns_buffer_begin(qstate->env->scratch_buffer),
sldns_buffer_limit(qstate->env->scratch_buffer));
sldns_buffer_limit(qstate->env->scratch_buffer),
qstate->return_msg->rep->ttl);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion cachedb/cachedb.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct cachedb_backend {

/** Store (env, cachedb_env, key, data, data_len) */
void (*store)(struct module_env*, struct cachedb_env*, char*,
uint8_t*, size_t);
uint8_t*, size_t, time_t);
};

#define CACHEDB_HASHSIZE 256 /* bit hash */
Expand Down
45 changes: 40 additions & 5 deletions cachedb/redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ struct redis_moddata {
struct timeval timeout; /* timeout for connection setup and commands */
};

static redisReply* redis_command(struct module_env*, struct cachedb_env*,
const char*, const uint8_t*, size_t);

static redisContext*
redis_connect(const struct redis_moddata* moddata)
{
Expand Down Expand Up @@ -90,6 +93,8 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
{
int i;
struct redis_moddata* moddata = NULL;
redisReply* rep;
int redis_reply_type = 0;

verbose(VERB_ALGO, "redis_init");

Expand All @@ -114,6 +119,26 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
for(i = 0; i < moddata->numctxs; i++)
moddata->ctxs[i] = redis_connect(moddata);
cachedb_env->backend_data = moddata;
if (env->cfg->redis_expire_records) {
/** check if setex command is supported */
rep = redis_command(env, cachedb_env, "SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0);
if(!rep) {
/** init failed, no response from redis server*/
log_err("redis_init: failed to init redis, the redis-expire-records option requires the SETEX command (redis >= 2.0.0)");
return 0;
}
redis_reply_type = rep->type;
freeReplyObject(rep);
switch (redis_reply_type) {
case REDIS_REPLY_STATUS:
break;
default:
/** init failed, setex command not supported */
log_err("redis_init: failed to init redis, the redis-expire-records option requires the SETEX command (redis >= 2.0.0)");
return 0;
}
}

return 1;
}

Expand Down Expand Up @@ -249,16 +274,26 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,

static void
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, uint8_t* data, size_t data_len)
char* key, uint8_t* data, size_t data_len, time_t ttl)
{
redisReply* rep;
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
int n;
int set_ttl = (int)(env->cfg->redis_expire_records && (!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1]; /* "SETEX " + key + " " + ttl + " %b" or "SET " + key + " %b"*/

if (!set_ttl) {
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 {
/* 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);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key, (uint32_t)ttl);
}

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);
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
log_err("redis_store: unexpected failure to build command");
return;
Expand Down
8 changes: 8 additions & 0 deletions doc/unbound.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -2130,6 +2130,14 @@ If this timeout expires Unbound closes the connection, treats it as
if the Redis server does not have the requested data, and will try to
re-establish a new connection later.
This option defaults to 100 milliseconds.
.TP
.B redis-expire-records: \fI<yes or no>
If redis record expiration is enabled. If yes, unbound sets ttl for redis
records so that redis can evict keys that have expired automatically. If
unbound is configured to serve expired entries and there is no expired ttl
set, this option is internally reverted to "no". Redis SETEX support required
(redis >= 2.0.0).
This option defaults to no.
.SS DNSTAP Logging Options
DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section.
This starts an extra thread (when compiled with threading) that writes
Expand Down
2 changes: 2 additions & 0 deletions util/config_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ config_create(void)
if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit;
cfg->redis_timeout = 100;
cfg->redis_server_port = 6379;
cfg->redis_expire_records = 0;
#endif /* USE_REDIS */
#endif /* USE_CACHEDB */
#ifdef USE_IPSET
Expand Down Expand Up @@ -1135,6 +1136,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "redis-server-host", redis_server_host)
else O_DEC(opt, "redis-server-port", redis_server_port)
else O_DEC(opt, "redis-timeout", redis_timeout)
else O_YNO(opt, "redis-expire-records", redis_expire_records)
#endif /* USE_REDIS */
#endif /* USE_CACHEDB */
#ifdef USE_IPSET
Expand Down
2 changes: 2 additions & 0 deletions util/config_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,8 @@ struct config_file {
int redis_server_port;
/** timeout (in ms) for communication with the redis server */
int redis_timeout;
/** set redis ttl value based on dns response ttl */
int redis_expire_records;
#endif
#endif

Expand Down
Loading

0 comments on commit 20aa782

Please sign in to comment.