The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
base.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or (at
6 * your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: 2283664397ac3ddc82bbc562bbdd1a52064c1bf9 $
20 * @file lib/redis/base.h
21 * @brief Common functions for interacting with Redis via hiredis
22 *
23 * @author Arran Cudbard-Bell
24 *
25 * @copyright 2015 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
26 * @copyright 2000,2006,2015 The FreeRADIUS server project
27 * @copyright 2011 TekSavvy Solutions (gabe@teksavvy.com)
28 */
29RCSIDH(redis_h, "$Id: 2283664397ac3ddc82bbc562bbdd1a52064c1bf9 $")
30
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>
35
36//DIAG_OFF(extra-semi-stmt)
37#include <hiredis/hiredis.h>
38//DIAG_ON(extra-semi-stmt)
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define MAX_REDIS_COMMAND_LEN 4096
45#define MAX_REDIS_ARGS 256
46
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
52
53#define REDIS_VERSION(_max, _min, _patch) (uint32_t) (_max << 24) | (_min << 16) | _patch
54
55typedef struct fr_redis_cluster_node_s fr_redis_cluster_node_t;
57
59extern size_t redis_reply_types_len;
61extern size_t redis_rcodes_len;
62
63/** Codes are ordered inversely by priority
64 *
65 * To simplify handling the return codes from pipelined commands,
66 * the lowest status code, and the reply which accompanies it should
67 * be returned to the redis cluster code.
68 */
69typedef enum {
70 REDIS_RCODE_SUCCESS = 0, //!< Operation was successful.
71 REDIS_RCODE_ERROR = -1, //!< Unrecoverable library/server error.
72 REDIS_RCODE_TRY_AGAIN = -2, //!< Try the operation again.
73 REDIS_RCODE_RECONNECT = -3, //!< Transitory error, caller should retry the operation
74 //!< with a new connection.
75 REDIS_RCODE_ASK = -4, //!< Attempt operation on an alternative node.
76 REDIS_RCODE_MOVE = -5, //!< Attempt operation on an alternative node with remap.
77 REDIS_RCODE_NO_SCRIPT = -6, //!< Script doesn't exist.
79
80typedef enum {
81 REDIS_ASYNC_RCODE_SUCCESS = 0, //!< Operation was successful.
82 REDIS_ASYNC_RCODE_ERROR = -1, //!< Unrecoverable error.
83 REDIS_ASYNC_RCODE_BOOTSTRAP = -2, //!< The caller should issue a request to bootstrap the cluster map.
84 REDIS_ASYNC_RCODE_GETMAP = -3, //!< The caller should issue a request to update the cluster map.
85
86 REDIS_ASYNC_RCODE_TRY_AGAIN = -4, //!< Try the operation again
87 REDIS_ASYNC_RCODE_ASK = -5, //!< Attempt operation on an alternative node.
88 REDIS_ASYNC_RCODE_MOVE = -6, //!< Attempt operation on an alternative node with remap.
89 REDIS_ASYNC_RCODE_NO_SCRIPT = -7, //!< Script doesn't exist.
90 REDIS_ASYNC_RCODE_FAIL = -8, //!< The command set trunk request has been failed.
92
93/** Connection handle, holding a redis context
94 */
95typedef struct {
96 redisContext *handle; //!< Hiredis context used when issuing commands.
97 fr_redis_cluster_node_t *node; //!< Node this connection is to.
99
109
110/** Configuration parameters for a redis connection
111 *
112 * @note should be passed as instance data to #module_rlm_connection_pool_init.
113 */
114typedef struct {
115 char const **hostname; //!< of Redis server.
116 uint16_t port; //!< of Redis daemon.
117 uint32_t database; //!< number on Redis server.
118 bool use_tls; //!< use TLS.
119 bool use_cluster_map;//!< use cluster map.
120
121 char const *username; //!< for acls.
122 char const *password; //!< to authenticate to Redis.
123
124 uint8_t max_nodes; //!< Maximum number of cluster nodes to connect to.
125 uint32_t max_redirects; //!< Maximum number of times we can be redirected.
126 uint32_t max_retries; //!< Maximum number of times we attempt a command
127 //!< when receiving successive -TRYAGAIN messages.
128 uint32_t max_alt; //!< Maximum alternative nodes to try.
129 fr_time_delta_t retry_delay; //!< How long to wait when we received a -TRYAGAIN
130 //!< message.
132
134
135 char const *log_prefix;
136
137 char const *module_name; //!< Module name for triggers.
138 char const *inst_name; //!< Instance name for triggers.
139
140 trunk_conf_t trunk_conf; //!< Configuration for trunk connections.
142
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) }
155
156void fr_redis_version_print(void);
157
158int redis_dict_init(void);
159
160/*
161 * Command and resulting parsing
162 */
164
165void fr_redis_reply_print(fr_log_lvl_t lvl, redisReply *reply, request_t *request, int idx,
166 fr_redis_rcode_t status);
167
168int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, redisReply *reply,
169 fr_type_t dst_type, fr_dict_attr_t const *dst_enumv,
170 bool box_error, bool shallow) CC_HINT(nonnull(2,3));
171
172int fr_redis_reply_to_map(TALLOC_CTX *ctx, map_list_t *out,
173 request_t *request, redisReply *key, redisReply *op, redisReply *value);
174
175int fr_redis_tuple_from_map(TALLOC_CTX *pool, char const *out[], size_t out_len[], map_t *map);
176
177fr_redis_rcode_t fr_redis_parse_version(char *out, size_t out_len, redisReply *reply);
178
179uint32_t fr_redis_version_num(char const *version);
180
181#ifdef __cplusplus
182}
183#endif
#define RCSIDH(h, id)
Definition build.h:561
Thread local state for a cluster.
Test enumeration values.
Definition dict_test.h:92
fr_log_lvl_t
Definition log.h:64
unsigned short uint16_t
fr_type_t
unsigned int uint32_t
unsigned char uint8_t
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.
Definition redis.c:229
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.
Definition redis.c:298
uint8_t max_nodes
Maximum number of cluster nodes to connect to.
Definition base.h:124
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.
Definition redis.c:611
fr_time_delta_t reconnection_delay
Definition base.h:133
fr_table_num_sorted_t const redis_rcodes[]
Definition redis.c:41
bool use_cluster_map
use cluster map.
Definition base.h:119
redisContext * handle
Hiredis context used when issuing commands.
Definition base.h:96
char const * username
for acls.
Definition base.h:121
int redis_dict_init(void)
Load the Redis dictionaries.
Definition redis.c:136
uint32_t database
number on Redis server.
Definition base.h:117
char const * inst_name
Instance name for triggers.
Definition base.h:138
trunk_conf_t trunk_conf
Configuration for trunk connections.
Definition base.h:140
fr_redis_async_rcode_t
Definition base.h:80
@ REDIS_ASYNC_RCODE_BOOTSTRAP
The caller should issue a request to bootstrap the cluster map.
Definition base.h:83
@ REDIS_ASYNC_RCODE_MOVE
Attempt operation on an alternative node with remap.
Definition base.h:88
@ REDIS_ASYNC_RCODE_ERROR
Unrecoverable error.
Definition base.h:82
@ REDIS_ASYNC_RCODE_GETMAP
The caller should issue a request to update the cluster map.
Definition base.h:84
@ REDIS_ASYNC_RCODE_ASK
Attempt operation on an alternative node.
Definition base.h:87
@ REDIS_ASYNC_RCODE_FAIL
The command set trunk request has been failed.
Definition base.h:90
@ REDIS_ASYNC_RCODE_TRY_AGAIN
Try the operation again.
Definition base.h:86
@ REDIS_ASYNC_RCODE_NO_SCRIPT
Script doesn't exist.
Definition base.h:89
@ REDIS_ASYNC_RCODE_SUCCESS
Operation was successful.
Definition base.h:81
fr_time_delta_t connection_timeout
Definition base.h:131
bool use_tls
use TLS.
Definition base.h:118
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.
Definition redis.c:550
fr_redis_cluster_node_t * node
Node this connection is to.
Definition base.h:97
uint16_t port
of Redis daemon.
Definition base.h:116
size_t redis_reply_types_len
Definition redis.c:39
uint32_t max_redirects
Maximum number of times we can be redirected.
Definition base.h:125
void fr_redis_version_print(void)
Print the version of libhiredis the server was built against.
Definition redis.c:107
uint32_t fr_redis_version_num(char const *version)
Convert version string into a 32bit unsigned integer for comparisons.
Definition redis.c:643
fr_redis_rcode_t fr_redis_command_status(fr_redis_conn_t *conn, redisReply *reply)
Check the reply for errors.
Definition redis.c:158
char const * module_name
Module name for triggers.
Definition base.h:137
fr_redis_packet_code_t
Definition base.h:100
@ FR_REDIS_CLUSTER_MAP_BOOTSTRAP
Definition base.h:102
@ FR_REDIS_CODE_MAX
Definition base.h:106
@ FR_REDIS_CLUSTER_MAP_GET
Definition base.h:103
@ FR_REDIS_INVALID
Definition base.h:101
@ FR_REDIS_DO_NOT_RESPOND
Definition base.h:107
@ FR_REDIS_CLUSTER_MAP_UPDATE
Definition base.h:104
@ FR_REDIS_CLUSTER_MAP_FAIL
Definition base.h:105
fr_table_num_sorted_t const redis_reply_types[]
Definition redis.c:31
size_t redis_rcodes_len
Definition redis.c:49
fr_time_delta_t retry_delay
How long to wait when we received a -TRYAGAIN message.
Definition base.h:129
char const * log_prefix
Definition base.h:135
char const ** hostname
of Redis server.
Definition base.h:115
fr_redis_rcode_t
Codes are ordered inversely by priority.
Definition base.h:69
@ REDIS_RCODE_RECONNECT
Transitory error, caller should retry the operation with a new connection.
Definition base.h:73
@ REDIS_RCODE_SUCCESS
Operation was successful.
Definition base.h:70
@ REDIS_RCODE_MOVE
Attempt operation on an alternative node with remap.
Definition base.h:76
@ REDIS_RCODE_TRY_AGAIN
Try the operation again.
Definition base.h:72
@ REDIS_RCODE_NO_SCRIPT
Script doesn't exist.
Definition base.h:77
@ REDIS_RCODE_ASK
Attempt operation on an alternative node.
Definition base.h:75
@ REDIS_RCODE_ERROR
Unrecoverable library/server error.
Definition base.h:71
char const * password
to authenticate to Redis.
Definition base.h:122
uint32_t max_alt
Maximum alternative nodes to try.
Definition base.h:128
struct fr_redis_cluster_node_s fr_redis_cluster_node_t
Definition base.h:55
uint32_t max_retries
Maximum number of times we attempt a command when receiving successive -TRYAGAIN messages.
Definition base.h:126
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.
Definition redis.c:457
Configuration parameters for a redis connection.
Definition base.h:114
Connection handle, holding a redis context.
Definition base.h:95
Value pair map.
Definition map.h:77
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
Common configuration parameters for a trunk.
Definition trunk.h:234
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1030