The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
base.h File Reference

Common functions for interacting with Redis via hiredis. More...

#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/map.h>
#include <freeradius-devel/server/module.h>
#include <hiredis/hiredis.h>
+ Include dependency graph for base.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  fr_redis_conf_t
 Configuration parameters for a redis connection. More...
 
struct  fr_redis_conn_t
 Connection handle, holding a redis context. More...
 

Macros

#define MAX_REDIS_ARGS   256
 
#define MAX_REDIS_COMMAND_LEN   4096
 
#define REDIS_COMMON_CONFIG
 
#define REDIS_DEFAULT_PORT   6379
 
#define REDIS_ERROR_ASK_STR   "ASK"
 
#define REDIS_ERROR_MOVED_STR   "MOVED"
 
#define REDIS_ERROR_NO_SCRIPT_STR   "NOSCRIPT"
 
#define REDIS_ERROR_TRY_AGAIN_STR   "TRYAGAIN"
 

Typedefs

typedef struct fr_redis_cluster_node_s fr_redis_cluster_node_t
 

Enumerations

enum  fr_redis_rcode_t {
  REDIS_RCODE_SUCCESS = 0 ,
  REDIS_RCODE_ERROR = -1 ,
  REDIS_RCODE_TRY_AGAIN = -2 ,
  REDIS_RCODE_RECONNECT = -3 ,
  REDIS_RCODE_ASK = -4 ,
  REDIS_RCODE_MOVE = -5 ,
  REDIS_RCODE_NO_SCRIPT = -6
}
 Codes are ordered inversely by priority. More...
 

Functions

fr_redis_rcode_t fr_redis_command_status (fr_redis_conn_t *conn, redisReply *reply)
 Check the reply for errors. More...
 
fr_redis_rcode_t fr_redis_get_version (char *out, size_t out_len, fr_redis_conn_t *conn)
 Get the version of Redis running on the remote server. More...
 
static void fr_redis_pipeline_free (redisReply *reply[], size_t num)
 
fr_redis_rcode_t fr_redis_pipeline_result (unsigned int *pipelined, fr_redis_rcode_t *rcode, redisReply *out[], size_t out_len, fr_redis_conn_t *conn)
 Simplifies handling of pipelined commands with Redis cluster. More...
 
static void fr_redis_reply_free (redisReply **reply)
 Wrap freeReplyObject so we consistently check for NULL pointers. More...
 
void fr_redis_reply_print (fr_log_lvl_t lvl, redisReply *reply, request_t *request, int idx)
 Print the response data in a useful treelike form. More...
 
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. More...
 
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. More...
 
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. More...
 
uint32_t fr_redis_version_num (char const *version)
 Convert version string into a 32bit unsigned integer for comparisons. More...
 
void fr_redis_version_print (void)
 Print the version of libhiredis the server was built against. More...
 

Variables

fr_table_num_sorted_t const redis_rcodes []
 
size_t redis_rcodes_len
 
fr_table_num_sorted_t const redis_reply_types []
 
size_t redis_reply_types_len
 

Detailed Description

Common functions for interacting with Redis via hiredis.

Id
ea3061098c4704c6f1e9f8770e24fd5309b719ce
Author
Arran Cudbard-Bell

Definition in file base.h.


Data Structure Documentation

◆ fr_redis_conf_t

struct fr_redis_conf_t

Configuration parameters for a redis connection.

Note
should be passed as instance data to module_rlm_connection_pool_init.

Definition at line 109 of file base.h.

+ Collaboration diagram for fr_redis_conf_t:
Data Fields
fr_time_delta_t connection_timeout
uint32_t database number on Redis server.
char const ** hostname of Redis server.
char const * log_prefix
uint32_t max_alt Maximum alternative nodes to try.
uint8_t max_nodes Maximum number of cluster nodes to connect to.
uint32_t max_redirects Maximum number of times we can be redirected.
uint32_t max_retries Maximum number of times we attempt a command when receiving successive -TRYAGAIN messages.
char const * password to authenticate to Redis.
uint16_t port of Redis daemon.
fr_time_delta_t reconnection_delay
fr_time_delta_t retry_delay How long to wait when we received a -TRYAGAIN message.
bool use_cluster_map use cluster map.
bool use_tls use TLS.
char const * username for acls.

◆ fr_redis_conn_t

struct fr_redis_conn_t

Connection handle, holding a redis context.

Definition at line 100 of file base.h.

+ Collaboration diagram for fr_redis_conn_t:
Data Fields
redisContext * handle Hiredis context used when issuing commands.
fr_redis_cluster_node_t * node Node this connection is to.

Macro Definition Documentation

◆ MAX_REDIS_ARGS

#define MAX_REDIS_ARGS   256

Definition at line 44 of file base.h.

◆ MAX_REDIS_COMMAND_LEN

#define MAX_REDIS_COMMAND_LEN   4096

Definition at line 43 of file base.h.

◆ REDIS_COMMON_CONFIG

#define REDIS_COMMON_CONFIG
Value:
{ FR_CONF_OFFSET("port", fr_redis_conf_t, port), .dflt = "6379" }, \
{ FR_CONF_OFFSET("database", fr_redis_conf_t, database), .dflt = "0" }, \
{ FR_CONF_OFFSET("use_tls", fr_redis_conf_t, use_tls), .dflt = "no" }, \
{ FR_CONF_OFFSET("use_cluster_map", fr_redis_conf_t, use_cluster_map), .dflt = "yes" }, \
{ FR_CONF_OFFSET_FLAGS("password", CONF_FLAG_SECRET, fr_redis_conf_t, password) }, \
{ FR_CONF_OFFSET("max_nodes", fr_redis_conf_t, max_nodes), .dflt = "20" }, \
{ FR_CONF_OFFSET("max_alt", fr_redis_conf_t, max_alt), .dflt = "3" }, \
{ FR_CONF_OFFSET("max_redirects", fr_redis_conf_t, max_redirects), .dflt = "2" }
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:256
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: cf_parse.h:406
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
Definition: cf_parse.h:420
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
Definition: cf_parse.h:410
static char const * hostname(char *buf, size_t buflen, uint32_t ipaddr)
Definition: radwho.c:133
Configuration parameters for a redis connection.
Definition: base.h:109
username
Definition: rlm_securid.c:420

Definition at line 133 of file base.h.

◆ REDIS_DEFAULT_PORT

#define REDIS_DEFAULT_PORT   6379

Definition at line 50 of file base.h.

◆ REDIS_ERROR_ASK_STR

#define REDIS_ERROR_ASK_STR   "ASK"

Definition at line 47 of file base.h.

◆ REDIS_ERROR_MOVED_STR

#define REDIS_ERROR_MOVED_STR   "MOVED"

Definition at line 46 of file base.h.

◆ REDIS_ERROR_NO_SCRIPT_STR

#define REDIS_ERROR_NO_SCRIPT_STR   "NOSCRIPT"

Definition at line 49 of file base.h.

◆ REDIS_ERROR_TRY_AGAIN_STR

#define REDIS_ERROR_TRY_AGAIN_STR   "TRYAGAIN"

Definition at line 48 of file base.h.

Typedef Documentation

◆ fr_redis_cluster_node_t

Definition at line 1 of file base.h.

Enumeration Type Documentation

◆ fr_redis_rcode_t

Codes are ordered inversely by priority.

To simplify handling the return codes from pipelined commands, the lowest status code, and the reply which accompanies it should be returned to the redis cluster code.

Enumerator
REDIS_RCODE_SUCCESS 

Operation was successful.

REDIS_RCODE_ERROR 

Unrecoverable library/server error.

REDIS_RCODE_TRY_AGAIN 

Try the operation again.

REDIS_RCODE_RECONNECT 

Transitory error, caller should retry the operation with a new connection.

REDIS_RCODE_ASK 

Attempt operation on an alternative node.

REDIS_RCODE_MOVE 

Attempt operation on an alternative node with remap.

REDIS_RCODE_NO_SCRIPT 

Script doesn't exist.

Definition at line 87 of file base.h.

Function Documentation

◆ fr_redis_command_status()

fr_redis_rcode_t fr_redis_command_status ( fr_redis_conn_t conn,
redisReply *  reply 
)

Check the reply for errors.

Parameters
[in]connused to issue the command.
[in]replyto process.
Returns
  • REDIS_RCODE_TRY_AGAIN - If the operation should be retries.
  • REDIS_RCODE_MOVED - If the key has been permanently moved.
  • REDIS_RCODE_ASK - If the key has been temporarily moved.
  • REDIS_RCODE_SUCCESS - if no errors.
  • REDIS_RCODE_ERROR - on command/server error.
  • REDIS_RCODE_NO_SCRIPT - script specified by evalsha doesn't exist.
  • REDIS_RCODE_RECONNECT - on connection error (probably needs reconnecting).

Definition at line 71 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_get_version()

fr_redis_rcode_t fr_redis_get_version ( char *  out,
size_t  out_len,
fr_redis_conn_t conn 
)

Get the version of Redis running on the remote server.

This can be useful for some modules, as it allows adaptive behaviour, or early termination.

Parameters
[out]outWhere to write the version string.
[in]out_lenLength of the version string buffer.
[in]connUsed to query the version string.
Returns

Definition at line 638 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_pipeline_free()

static void fr_redis_pipeline_free ( redisReply *  reply[],
size_t  num 
)
inlinestatic

Definition at line 70 of file base.h.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_pipeline_result()

fr_redis_rcode_t fr_redis_pipeline_result ( unsigned int *  pipelined,
fr_redis_rcode_t rcode,
redisReply *  out[],
size_t  out_len,
fr_redis_conn_t conn 
)

Simplifies handling of pipelined commands with Redis cluster.

Retrieve all available pipelined responses, and write them to the array.

On encountering an error, all previously retrieved responses are freed, and the reply containing the error is written to the first element of out. All responses after the error are also freed.

If the number of responses != pipelined, that's also an error, a very serious one, in libhiredis or Redis. We can't really do much here apart from error out.

Parameters
[out]pipelinedNumber of pipelined commands we sent to the server.
[out]rcodeStatus of the first errored response, or REDIS_RCODE_SUCCESS if all responses were processed.
[out]outWhere to write the replies from pipelined commands. Will contain exactly 1 element on error WHICH MUST BE FREED, else the number passed in pipelined.
[in]out_lennumber of elements in out.
[in]connthe pipelined commands were issued on.
Returns

Definition at line 535 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_reply_free()

static void fr_redis_reply_free ( redisReply **  reply)
inlinestatic

Wrap freeReplyObject so we consistently check for NULL pointers.

Older versions such as 0.10 (which ship with Ubuntu <= 14.10) don't check for NULL pointer before attempting to free, so we get a NULL pointer dereference in some cases.

Rather than go back through the many calls to freeReplyObject and attempt to determine code paths that may result in it being called on a NULL pointer, we use this to always check.

Definition at line 64 of file base.h.

+ Here is the caller graph for this function:

◆ fr_redis_reply_print()

void fr_redis_reply_print ( fr_log_lvl_t  lvl,
redisReply *  reply,
request_t request,
int  idx 
)

Print the response data in a useful treelike form.

Parameters
[in]lvlto print data at.
[in]replyto print.
[in]requestThe current request.
[in]idxResponse number.

Definition at line 141 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_reply_to_map()

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.

The maps can then be applied using map_to_request.

Parameters
[in,out]ctxto allocate maps in.
[out]outWhere to write the head of the new maps list.
[in]requestThe current request.
[in]keyto process.
[in]opto process.
[in]valueto process.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 365 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_reply_to_value_box()

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.

Will work with REDIS_REPLY_STRING (which is converted to FR_TYPE_STRING then cast to dst_type), or REDIS_REPLY_INTEGER (which is converted to FR_TYPE_UINT64, then cast to dst_type).

Note
Any unsupported types will trigger an assert. You must check the reply type prior to calling this function.
Parameters
[in,out]ctxto allocate any buffers in.
[out]outWhere to write the cast type.
[in]replyto process.
[in]dst_typeto convert to. May be FR_TYPE_VOID to infer type.
[in]dst_enumvUsed to convert string types to integers for attribute with enumerated values.
[in]box_errorIf true then REDIS_REPLY_ERROR will be copied to a box, otherwise we'll return and error with the contents of the error available on the thread local error stack.
[in]shallowIf true, we shallow copy strings.
Returns
  • 1 if we received a NIL reply.
  • 0 on success.
  • -1 on cast or parse failure.

Definition at line 206 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_tuple_from_map()

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.

  • Integer types will be encoded as integers.
  • Strings and octets will be encoded in their raw form.
  • Other types will be converted to their printable form and will be encoded as strings.
Note
lhs must be a TMPL_TYPE_ATTR.
rhs must be a TMPL_TYPE_DATA.
Parameters
poolto allocate any buffers in.
outWhere to write pointers to the member of the tuple. Unused elements should be a multiple of three, and it should have at least three unused elements.
out_lenWhere to write the size of the data pointed to by the equivalent index in the out array.
mapto convert.
Returns
0 on success. -1 on failure.

Definition at line 459 of file redis.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_redis_version_num()

uint32_t fr_redis_version_num ( char const *  version)

Convert version string into a 32bit unsigned integer for comparisons.

Parameters
[in]versionstring to parse.
Returns
32bit unsigned integer representing the version string.

Definition at line 688 of file redis.c.

+ Here is the caller graph for this function:

◆ fr_redis_version_print()

void fr_redis_version_print ( void  )

Print the version of libhiredis the server was built against.

Definition at line 53 of file redis.c.

+ Here is the caller graph for this function:

Variable Documentation

◆ redis_rcodes

fr_table_num_sorted_t const redis_rcodes[]
extern

Definition at line 40 of file redis.c.

◆ redis_rcodes_len

size_t redis_rcodes_len
extern

Definition at line 48 of file redis.c.

◆ redis_reply_types

fr_table_num_sorted_t const redis_reply_types[]
extern

Definition at line 30 of file redis.c.

◆ redis_reply_types_len

size_t redis_reply_types_len
extern

Definition at line 38 of file redis.c.