From: Marko Rizvic Date: Fri, 15 Dec 2017 22:05:23 +0000 (+0100) Subject: implemented redis query and connection timeout X-Git-Tag: release_3_0_16~25^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8fccfd58e2d19f6d63b12d92a6e75bb3ed203cdb;p=thirdparty%2Ffreeradius-server.git implemented redis query and connection timeout --- diff --git a/raddb/mods-available/redis b/raddb/mods-available/redis index 0ef86751acd..7952ee4eceb 100644 --- a/raddb/mods-available/redis +++ b/raddb/mods-available/redis @@ -19,6 +19,9 @@ redis { # We recommend using a strong password. # password = thisisreallysecretandhardtoguess + # Set connection and query timeout for rlm_redis + query_timeout = 5 + # # Information for the connection pool. The configuration items # below are the same for all modules which use the new diff --git a/src/modules/rlm_redis/rlm_redis.c b/src/modules/rlm_redis/rlm_redis.c index 19c51d07e6e..f7e6749fba7 100644 --- a/src/modules/rlm_redis/rlm_redis.c +++ b/src/modules/rlm_redis/rlm_redis.c @@ -36,6 +36,7 @@ static const CONF_PARSER module_config[] = { { "port", FR_CONF_OFFSET(PW_TYPE_SHORT, REDIS_INST, port), "6379" }, { "database", FR_CONF_OFFSET(PW_TYPE_INTEGER, REDIS_INST, database), "0" }, { "password", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_SECRET, REDIS_INST, password), NULL }, + { "query_timeout", FR_CONF_OFFSET(PW_TYPE_SHORT, REDIS_INST, query_timeout), "5" }, CONF_PARSER_TERMINATOR }; @@ -61,17 +62,26 @@ static void *mod_conn_create(TALLOC_CTX *ctx, void *instance) redisContext *conn; redisReply *reply = NULL; char buffer[1024]; + struct timeval tv; + tv.tv_sec = inst->query_timeout; + tv.tv_usec = 0; - conn = redisConnect(inst->hostname, inst->port); + conn = redisConnectWithTimeout(inst->hostname, inst->port, tv); if (!conn) { - ERROR("rlm_redis (%s): Failed calling redisConnect('%s', %d)", - inst->xlat_name, inst->hostname, inst->port); + ERROR("rlm_redis (%s): Failed calling redisConnectWithTimeout('%s', %d, %d)", + inst->xlat_name, inst->hostname, inst->port, inst->query_timeout); return NULL; } if (conn && conn->err) { - ERROR("rlm_redis (%s): Problems with redisConnect('%s', %d), %s", - inst->xlat_name, inst->hostname, inst->port, redisReplyReaderGetError(conn)); + ERROR("rlm_redis (%s): Problems with redisConnectWithTimeout('%s', %d, %d), %s", + inst->xlat_name, inst->hostname, inst->port, inst->query_timeout, redisReplyReaderGetError(conn)); + redisFree(conn); + return NULL; + } + + if ( redisSetTimeout(conn, tv) == REDIS_ERR ) { + ERROR("rlm_redis (%s): redisSetTimeout('%s', %d) returned REDIS_ERR", inst->xlat_name, inst->hostname, inst->port); redisFree(conn); return NULL; } @@ -215,6 +225,9 @@ int rlm_redis_query(REDISSOCK **dissocket_p, REDIS_INST *inst, int argc; char const *argv[MAX_REDIS_ARGS]; char argv_buf[MAX_QUERY_LEN]; + struct timeval tv; + tv.tv_sec = inst->query_timeout; + tv.tv_usec = 0; if (!query || !*query || !inst || !dissocket_p) { return -1; @@ -239,7 +252,7 @@ int rlm_redis_query(REDISSOCK **dissocket_p, REDIS_INST *inst, return -1; } - dissocket->reply = redisCommand(dissocket->conn, query); + dissocket->reply = redisCommand(dissocket->conn, query, tv); if (!dissocket->reply) { RERROR("Failed after re-connect"); fr_connection_close(inst->pool, dissocket, NULL); diff --git a/src/modules/rlm_redis/rlm_redis.h b/src/modules/rlm_redis/rlm_redis.h index 3570b40399b..63dde691d40 100644 --- a/src/modules/rlm_redis/rlm_redis.h +++ b/src/modules/rlm_redis/rlm_redis.h @@ -47,6 +47,7 @@ typedef struct rlm_redis_t { uint16_t port; uint32_t database; char const *password; + uint16_t query_timeout; fr_connection_pool_t *pool; int (*redis_query)(REDISSOCK **dissocket_p, REDIS_INST *inst, char const *query, REQUEST *request);