The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
cluster.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or (at
7  * your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 /**
20  * $Id: f0a0aaf99fa4c22e26d1d8c7a71b3257c6e0a39a $
21  * @file cluster.h
22  * @brief Common functions for interacting with Redis cluster via Hiredis
23  *
24  * @author Arran Cudbard-Bell
25  *
26  * @copyright 2015 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
27  * @copyright 2015 Network RADIUS (legal@networkradius.com)
28  * @copyright 2015 The FreeRADIUS server project
29  */
30 RCSIDH(cluster_h, "$Id: f0a0aaf99fa4c22e26d1d8c7a71b3257c6e0a39a $")
31 
32 #include <freeradius-devel/server/pool.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
41 
42 /** Redis connection sequence state
43  *
44  * Tracks how many operations we've performed attempting to execute a single command.
45  *
46  * Used by callers of the cluster code. Allocated on the stack and passed to
47  * #fr_redis_cluster_state_init and #fr_redis_cluster_state_next.
48  */
49 typedef struct {
50  bool close_conn; //!< Set by caller of fr_redis_cluster_state_next,
51  //!< to indicate that connection must be closed, as it's
52  //!< now in an unknown state.
53 
54  uint8_t const *key; //!< Key we performed hashing on.
55  size_t key_len; //!< Length of the key.
56 
57  fr_redis_cluster_node_t *node; //!< Node we're communicating with.
58  uint32_t redirects; //!< How many redirects have we followed.
59 
60  uint32_t retries; //!< How many times we've received TRYAGAIN
61  uint32_t in_pool; //!< How many available connections are there in the pool.
62  uint32_t reconnects; //!< How many connections we've tried in this pool.
64 
65 /** Return values for internal functions
66  */
67 typedef enum {
68  FR_REDIS_CLUSTER_RCODE_IGNORED = 1, //!< Operation ignored.
69  FR_REDIS_CLUSTER_RCODE_SUCCESS = 0, //!< Operation completed successfully.
70  FR_REDIS_CLUSTER_RCODE_FAILED = -1, //!< Operation failed.
71  FR_REDIS_CLUSTER_RCODE_NO_CONNECTION = -2, //!< Operation failed because we couldn't find
72  //!< a live connection.
73  FR_REDIS_CLUSTER_RCODE_BAD_INPUT = -3 //!< Validation error.
75 
78 
80 
81 /*
82  * Callback for the connection pool to create a new connection
83  */
84 void *fr_redis_cluster_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout);
85 
86 /*
87  * Functions to resolve a key to a cluster node
88  */
90  uint8_t const *key, size_t key_len);
91 
93  fr_redis_cluster_key_slot_t const *key_slot);
94 
96  fr_redis_cluster_key_slot_t const *key_slot,
97  uint8_t slave_num);
98 
100 
102 
103 
104 
105 /*
106  * Reserve/release connections, follow redirects, reconnect
107  * connections implement retry delays.
108  */
110  fr_redis_cluster_t *cluster, request_t *request,
111  uint8_t const *key, size_t key_len, bool read_only);
112 
114  fr_redis_cluster_t *cluster, request_t *request,
115  fr_redis_rcode_t status, redisReply **reply);
116 
117 /*
118  * Useful for running commands over every node, such as PING
119  * or KEYS.
120  */
122  fr_socket_t *node, bool create);
124  fr_redis_cluster_t *cluster, bool is_master, bool is_slave);
125 
126 /*
127  * Initialise a new cluster connection, and perform initial mapping.
128  */
129 bool fr_redis_cluster_min_version(fr_redis_cluster_t *cluster, char const *min_version);
130 
132  CONF_SECTION *module,
134  bool enable_triggers,
135  char const *log_prefix,
136  char const *trigger_prefix,
137  fr_pair_list_t *trigger_args);
138 
139 #ifdef __cplusplus
140 }
141 #endif
#define RCSIDH(h, id)
Definition: build.h:445
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
A redis cluster.
Definition: cluster.c:247
Indexes in the fr_redis_cluster_node_t array for a single key slot.
Definition: cluster.c:237
A Redis cluster node.
Definition: cluster.c:209
fr_redis_rcode_t fr_redis_cluster_state_next(fr_redis_cluster_state_t *state, fr_redis_conn_t **conn, fr_redis_cluster_t *cluster, request_t *request, fr_redis_rcode_t status, redisReply **reply)
Get the next connection to attempt a command against.
Definition: cluster.c:1859
size_t key_len
Length of the key.
Definition: cluster.h:55
fr_redis_cluster_key_slot_t const * fr_redis_cluster_slot_by_key(fr_redis_cluster_t *cluster, request_t *request, uint8_t const *key, size_t key_len)
Implements the key slot selection scheme used by freeradius.
Definition: cluster.c:1599
bool close_conn
Set by caller of fr_redis_cluster_state_next, to indicate that connection must be closed,...
Definition: cluster.h:50
ssize_t fr_redis_cluster_node_addr_by_role(TALLOC_CTX *ctx, fr_socket_t *out[], fr_redis_cluster_t *cluster, bool is_master, bool is_slave)
Return an array of IP addresses belonging to masters or slaves.
Definition: cluster.c:2134
size_t fr_redis_cluster_rcodes_table_len
Definition: cluster.c:284
int fr_redis_cluster_port(uint16_t *out, fr_redis_cluster_node_t const *node)
Return the port of a particular node.
Definition: cluster.c:1685
int fr_redis_cluster_pool_by_node_addr(fr_pool_t **pool, fr_redis_cluster_t *cluster, fr_socket_t *node, bool create)
Get the pool associated with a node in the cluster.
Definition: cluster.c:2066
void * fr_redis_cluster_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout)
Create a new connection to a Redis node.
Definition: cluster.c:1464
uint32_t retries
How many times we've received TRYAGAIN.
Definition: cluster.h:60
fr_redis_cluster_rcode_t fr_redis_cluster_remap(request_t *request, fr_redis_cluster_t *cluster, fr_redis_conn_t *conn)
Perform a runtime remap of the cluster.
Definition: cluster.c:1005
uint32_t reconnects
How many connections we've tried in this pool.
Definition: cluster.h:62
uint8_t const * key
Key we performed hashing on.
Definition: cluster.h:54
fr_redis_cluster_node_t const * fr_redis_cluster_slave(fr_redis_cluster_t *cluster, fr_redis_cluster_key_slot_t const *key_slot, uint8_t slave_num)
Return the slave node that would be used for a particular key.
Definition: cluster.c:1651
fr_redis_cluster_rcode_t
Return values for internal functions.
Definition: cluster.h:67
@ FR_REDIS_CLUSTER_RCODE_IGNORED
Operation ignored.
Definition: cluster.h:68
@ FR_REDIS_CLUSTER_RCODE_FAILED
Operation failed.
Definition: cluster.h:70
@ FR_REDIS_CLUSTER_RCODE_SUCCESS
Operation completed successfully.
Definition: cluster.h:69
@ FR_REDIS_CLUSTER_RCODE_BAD_INPUT
Validation error.
Definition: cluster.h:73
@ FR_REDIS_CLUSTER_RCODE_NO_CONNECTION
Operation failed because we couldn't find a live connection.
Definition: cluster.h:71
fr_redis_rcode_t fr_redis_cluster_state_init(fr_redis_cluster_state_t *state, fr_redis_conn_t **conn, fr_redis_cluster_t *cluster, request_t *request, uint8_t const *key, size_t key_len, bool read_only)
Resolve a key to a pool, and reserve a connection in that pool.
Definition: cluster.c:1737
fr_redis_cluster_node_t const * fr_redis_cluster_master(fr_redis_cluster_t *cluster, fr_redis_cluster_key_slot_t const *key_slot)
Return the master node that would be used for a particular key.
Definition: cluster.c:1635
uint32_t redirects
How many redirects have we followed.
Definition: cluster.h:58
fr_redis_cluster_t * fr_redis_cluster_alloc(TALLOC_CTX *ctx, CONF_SECTION *module, fr_redis_conf_t *conf, bool enable_triggers, char const *log_prefix, char const *trigger_prefix, fr_pair_list_t *trigger_args)
Allocate and initialise a new cluster structure.
Definition: cluster.c:2257
fr_table_num_sorted_t const fr_redis_cluster_rcodes_table[]
Definition: cluster.c:277
fr_redis_cluster_node_t * node
Node we're communicating with.
Definition: cluster.h:57
int fr_redis_cluster_ipaddr(fr_ipaddr_t *out, fr_redis_cluster_node_t const *node)
Return the ipaddr of a particular node.
Definition: cluster.c:1668
uint32_t in_pool
How many available connections are there in the pool.
Definition: cluster.h:61
bool fr_redis_cluster_min_version(fr_redis_cluster_t *cluster, char const *min_version)
Check if members of the cluster are above a certain version.
Definition: cluster.c:2198
Redis connection sequence state.
Definition: cluster.h:49
static fr_time_delta_t timeout
Definition: dhcpclient.c:54
IPv4/6 prefix.
Definition: merged_model.c:272
unsigned short uint16_t
Definition: merged_model.c:31
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
A connection pool.
Definition: pool.c:85
static rs_t * conf
Definition: radsniff.c:53
fr_redis_rcode_t
Codes are ordered inversely by priority.
Definition: base.h:87
Configuration parameters for a redis connection.
Definition: base.h:109
Connection handle, holding a redis context.
Definition: base.h:100
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:45
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
Holds information necessary for binding or connecting to a socket.
Definition: socket.h:63
static size_t char ** out
Definition: value.h:984