29RCSIDH(redis_h,
"$Id: 2283664397ac3ddc82bbc562bbdd1a52064c1bf9 $")
31#include <freeradius-devel/server/base.h>
32#include <freeradius-devel/server/map.h>
33#include <freeradius-devel/server/module.h>
34#include <freeradius-devel/server/trunk.h>
37#include <hiredis/hiredis.h>
44#define MAX_REDIS_COMMAND_LEN 4096
45#define MAX_REDIS_ARGS 256
47#define REDIS_ERROR_MOVED_STR "MOVED"
48#define REDIS_ERROR_ASK_STR "ASK"
49#define REDIS_ERROR_TRY_AGAIN_STR "TRYAGAIN"
50#define REDIS_ERROR_NO_SCRIPT_STR "NOSCRIPT"
51#define REDIS_DEFAULT_PORT 6379
53#define REDIS_VERSION(_max, _min, _patch) (uint32_t) (_max << 24) | (_min << 16) | _patch
143#define REDIS_COMMON_CONFIG \
144 { FR_CONF_OFFSET_FLAGS("server", CONF_FLAG_REQUIRED | CONF_FLAG_MULTI, fr_redis_conf_t, hostname) }, \
145 { FR_CONF_OFFSET("port", fr_redis_conf_t, port), .dflt = "6379" }, \
146 { FR_CONF_OFFSET("database", fr_redis_conf_t, database), .dflt = "0" }, \
147 { FR_CONF_OFFSET("use_tls", fr_redis_conf_t, use_tls), .dflt = "no" }, \
148 { FR_CONF_OFFSET("use_cluster_map", fr_redis_conf_t, use_cluster_map), .dflt = "yes" }, \
149 { FR_CONF_OFFSET("username", fr_redis_conf_t, username) }, \
150 { FR_CONF_OFFSET_FLAGS("password", CONF_FLAG_SECRET, fr_redis_conf_t, password) }, \
151 { FR_CONF_OFFSET("max_nodes", fr_redis_conf_t, max_nodes), .dflt = "20" }, \
152 { FR_CONF_OFFSET("max_alt", fr_redis_conf_t, max_alt), .dflt = "3" }, \
153 { FR_CONF_OFFSET("max_redirects", fr_redis_conf_t, max_redirects), .dflt = "2" }, \
154 { FR_CONF_OFFSET_SUBSECTION("pool", 0, fr_redis_conf_t, trunk_conf, trunk_config) }
170 bool box_error,
bool shallow) CC_HINT(
nonnull(2,3));
173 request_t *request, redisReply *key, redisReply *op, redisReply *
value);
Thread local state for a cluster.
void fr_redis_reply_print(fr_log_lvl_t lvl, redisReply *reply, request_t *request, int idx, fr_redis_rcode_t status)
Print the response data in a useful treelike form.
int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, redisReply *reply, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, bool box_error, bool shallow))
Convert a string or integer type to fr_value_box_t of specified type.
uint8_t max_nodes
Maximum number of cluster nodes to connect to.
fr_redis_rcode_t fr_redis_parse_version(char *out, size_t out_len, redisReply *reply)
Parse the reply from the Redis command INFO SERVER to extract the version.
fr_time_delta_t reconnection_delay
fr_table_num_sorted_t const redis_rcodes[]
bool use_cluster_map
use cluster map.
redisContext * handle
Hiredis context used when issuing commands.
char const * username
for acls.
int redis_dict_init(void)
Load the Redis dictionaries.
uint32_t database
number on Redis server.
char const * inst_name
Instance name for triggers.
trunk_conf_t trunk_conf
Configuration for trunk connections.
@ REDIS_ASYNC_RCODE_BOOTSTRAP
The caller should issue a request to bootstrap the cluster map.
@ REDIS_ASYNC_RCODE_MOVE
Attempt operation on an alternative node with remap.
@ REDIS_ASYNC_RCODE_ERROR
Unrecoverable error.
@ REDIS_ASYNC_RCODE_GETMAP
The caller should issue a request to update the cluster map.
@ REDIS_ASYNC_RCODE_ASK
Attempt operation on an alternative node.
@ REDIS_ASYNC_RCODE_FAIL
The command set trunk request has been failed.
@ REDIS_ASYNC_RCODE_TRY_AGAIN
Try the operation again.
@ REDIS_ASYNC_RCODE_NO_SCRIPT
Script doesn't exist.
@ REDIS_ASYNC_RCODE_SUCCESS
Operation was successful.
fr_time_delta_t connection_timeout
int fr_redis_tuple_from_map(TALLOC_CTX *pool, char const *out[], size_t out_len[], map_t *map)
Add a single map pair to an existing command string as three elements.
fr_redis_cluster_node_t * node
Node this connection is to.
uint16_t port
of Redis daemon.
size_t redis_reply_types_len
uint32_t max_redirects
Maximum number of times we can be redirected.
void fr_redis_version_print(void)
Print the version of libhiredis the server was built against.
uint32_t fr_redis_version_num(char const *version)
Convert version string into a 32bit unsigned integer for comparisons.
fr_redis_rcode_t fr_redis_command_status(fr_redis_conn_t *conn, redisReply *reply)
Check the reply for errors.
char const * module_name
Module name for triggers.
@ FR_REDIS_CLUSTER_MAP_BOOTSTRAP
@ FR_REDIS_CLUSTER_MAP_GET
@ FR_REDIS_DO_NOT_RESPOND
@ FR_REDIS_CLUSTER_MAP_UPDATE
@ FR_REDIS_CLUSTER_MAP_FAIL
fr_table_num_sorted_t const redis_reply_types[]
fr_time_delta_t retry_delay
How long to wait when we received a -TRYAGAIN message.
char const ** hostname
of Redis server.
fr_redis_rcode_t
Codes are ordered inversely by priority.
@ REDIS_RCODE_RECONNECT
Transitory error, caller should retry the operation with a new connection.
@ REDIS_RCODE_SUCCESS
Operation was successful.
@ REDIS_RCODE_MOVE
Attempt operation on an alternative node with remap.
@ REDIS_RCODE_TRY_AGAIN
Try the operation again.
@ REDIS_RCODE_NO_SCRIPT
Script doesn't exist.
@ REDIS_RCODE_ASK
Attempt operation on an alternative node.
@ REDIS_RCODE_ERROR
Unrecoverable library/server error.
char const * password
to authenticate to Redis.
uint32_t max_alt
Maximum alternative nodes to try.
struct fr_redis_cluster_node_s fr_redis_cluster_node_t
uint32_t max_retries
Maximum number of times we attempt a command when receiving successive -TRYAGAIN messages.
int fr_redis_reply_to_map(TALLOC_CTX *ctx, map_list_t *out, request_t *request, redisReply *key, redisReply *op, redisReply *value)
Convert a pair of redis reply objects to a map.
Configuration parameters for a redis connection.
Connection handle, holding a redis context.
An element in a lexicographically sorted array of name to num mappings.
A time delta, a difference in time measured in nanoseconds.
Common configuration parameters for a trunk.
static size_t char ** out