Skip to content

Commit

Permalink
- Add redis-command-timeout: 20 and redis-connect-timeout: 200,
Browse files Browse the repository at this point in the history
  that can set the timeout separately for commands and the
  connection set up to the redis server. If they are not
  specified, the redis-timeout value is used.
  • Loading branch information
wcawijngaards committed Sep 17, 2024
1 parent 606e262 commit 5e9b629
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 7 deletions.
29 changes: 23 additions & 6 deletions cachedb/redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ struct redis_moddata {
int server_port; /* server's TCP port */
const char* server_path; /* server's unix path, or "", NULL if unused */
const char* server_password; /* server's AUTH password, or "", NULL if unused */
struct timeval timeout; /* timeout for connection setup and commands */
struct timeval command_timeout; /* timeout for commands */
struct timeval connect_timeout; /* timeout for connect */
int logical_db; /* the redis logical database to use */
};

Expand Down Expand Up @@ -88,10 +89,10 @@ redis_connect(const struct redis_moddata* moddata)

if(moddata->server_path && moddata->server_path[0]!=0) {
ctx = redisConnectUnixWithTimeout(moddata->server_path,
moddata->timeout);
moddata->connect_timeout);
} else {
ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->timeout);
moddata->server_port, moddata->connect_timeout);
}
if(!ctx || ctx->err) {
const char *errstr = "out of memory";
Expand All @@ -100,7 +101,7 @@ redis_connect(const struct redis_moddata* moddata)
log_err("failed to connect to redis server: %s", errstr);
goto fail;
}
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
if(redisSetTimeout(ctx, moddata->command_timeout) != REDIS_OK) {
log_err("failed to set redis timeout");
goto fail;
}
Expand Down Expand Up @@ -159,8 +160,24 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
moddata->server_port = env->cfg->redis_server_port;
moddata->server_path = env->cfg->redis_server_path;
moddata->server_password = env->cfg->redis_server_password;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
moddata->command_timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->command_timeout.tv_usec =
(env->cfg->redis_timeout % 1000) * 1000;
moddata->connect_timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->connect_timeout.tv_usec =
(env->cfg->redis_timeout % 1000) * 1000;
if(env->cfg->redis_command_timeout != 0) {
moddata->command_timeout.tv_sec =
env->cfg->redis_command_timeout / 1000;
moddata->command_timeout.tv_usec =
(env->cfg->redis_command_timeout % 1000) * 1000;
}
if(env->cfg->redis_connect_timeout != 0) {
moddata->connect_timeout.tv_sec =
env->cfg->redis_connect_timeout / 1000;
moddata->connect_timeout.tv_usec =
(env->cfg->redis_connect_timeout % 1000) * 1000;
}
moddata->logical_db = env->cfg->redis_logical_db;
for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(moddata);
Expand Down
6 changes: 6 additions & 0 deletions doc/Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
17 September 2024: Wouter
- Add redis-command-timeout: 20 and redis-connect-timeout: 200,
that can set the timeout separately for commands and the
connection set up to the redis server. If they are not
specified, the redis-timeout value is used.

16 September 2024: Wouter
- Merge #1140: Fix spelling mistake in comments.

Expand Down
4 changes: 4 additions & 0 deletions doc/example.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,10 @@ remote-control:
# # redis-server-password: ""
# # timeout (in ms) for communication with the redis server
# redis-timeout: 100
# # timeout (in ms) for commands, if 0, uses redis-timeout.
# redis-command-timeout: 0
# # timeout (in ms) for connection set up, if 0, uses redis-timeout.
# redis-connect-timeout: 0
# # set timeout on redis records based on DNS response TTL
# redis-expire-records: no
# # redis logical database to use, 0 is the default database.
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 @@ -2810,6 +2810,14 @@ 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-command-timeout: \fI<msec>\fR
The timeout to use for redis commands, in milliseconds. If 0, it uses the
redis\-timeout value. The default is 0.
.TP
.B redis-connect-timeout: \fI<msec>\fR
The timeout to use for redis connection set up, in milliseconds. If 0, it
uses the redis\-timeout value. The default is 0.
.TP
.B redis-expire-records: \fI<yes or no>
If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis
records so that Redis can evict keys that have expired automatically. If
Expand Down
4 changes: 4 additions & 0 deletions util/config_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ config_create(void)
cfg->redis_server_path = NULL;
cfg->redis_server_password = NULL;
cfg->redis_timeout = 100;
cfg->redis_command_timeout = 0;
cfg->redis_connect_timeout = 0;
cfg->redis_server_port = 6379;
cfg->redis_expire_records = 0;
cfg->redis_logical_db = 0;
Expand Down Expand Up @@ -1364,6 +1366,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "redis-server-path", redis_server_path)
else O_STR(opt, "redis-server-password", redis_server_password)
else O_DEC(opt, "redis-timeout", redis_timeout)
else O_DEC(opt, "redis-command-timeout", redis_command_timeout)
else O_DEC(opt, "redis-connect-timeout", redis_connect_timeout)
else O_YNO(opt, "redis-expire-records", redis_expire_records)
else O_DEC(opt, "redis-logical-db", redis_logical_db)
#endif /* USE_REDIS */
Expand Down
4 changes: 4 additions & 0 deletions util/config_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,10 @@ struct config_file {
char* redis_server_password;
/** timeout (in ms) for communication with the redis server */
int redis_timeout;
/** timeout (in ms) for redis commands */
int redis_command_timeout;
/** timeout (in ms) for redis connection set up */
int redis_connect_timeout;
/** set timeout on redis records based on DNS response ttl */
int redis_expire_records;
/** set the redis logical database upon connection */
Expand Down
2 changes: 2 additions & 0 deletions util/configlexer.lex
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) }
redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) }
redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
redis-command-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISCOMMANDTIMEOUT) }
redis-connect-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISCONNECTTIMEOUT) }
redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) }
redis-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) }
ipset{COLON} { YDVAR(0, VAR_IPSET) }
Expand Down
30 changes: 29 additions & 1 deletion util/configparser.y
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
%token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD
%token VAR_CACHEDB_REDISLOGICALDB
%token VAR_CACHEDB_REDISCOMMANDTIMEOUT VAR_CACHEDB_REDISCONNECTTIMEOUT
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
Expand Down Expand Up @@ -3838,7 +3839,8 @@ contents_cachedb: contents_cachedb content_cachedb
content_cachedb: cachedb_backend_name | cachedb_secret_seed |
redis_server_host | redis_server_port | redis_timeout |
redis_expire_records | redis_server_path | redis_server_password |
cachedb_no_store | redis_logical_db | cachedb_check_when_serve_expired
cachedb_no_store | redis_logical_db | cachedb_check_when_serve_expired |
redis_command_timeout | redis_connect_timeout
;
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
{
Expand Down Expand Up @@ -3954,6 +3956,32 @@ redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
free($2);
}
;
redis_command_timeout: VAR_CACHEDB_REDISCOMMANDTIMEOUT STRING_ARG
{
#if defined(USE_CACHEDB) && defined(USE_REDIS)
OUTYY(("P(redis_command_timeout:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("redis command timeout value expected");
else cfg_parser->cfg->redis_command_timeout = atoi($2);
#else
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
#endif
free($2);
}
;
redis_connect_timeout: VAR_CACHEDB_REDISCONNECTTIMEOUT STRING_ARG
{
#if defined(USE_CACHEDB) && defined(USE_REDIS)
OUTYY(("P(redis_connect_timeout:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("redis connect timeout value expected");
else cfg_parser->cfg->redis_connect_timeout = atoi($2);
#else
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
#endif
free($2);
}
;
redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG
{
#if defined(USE_CACHEDB) && defined(USE_REDIS)
Expand Down

0 comments on commit 5e9b629

Please sign in to comment.