All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rlm_cache.h
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /*
18  * $Id: 9fc02608255c6494115856a58c41095dbeb92d9b $
19  * @file rlm_cache.h
20  * @brief Cache values and merge them back into future requests.
21  *
22  * @copyright 2014 The FreeRADIUS server project
23  * @copyright 2014 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
24  */
25 RCSIDH(cache_h, "$Id: 9fc02608255c6494115856a58c41095dbeb92d9b $")
26 
27 #include <freeradius-devel/radiusd.h>
28 
30 
31 typedef void rlm_cache_handle_t;
32 
33 #define MAX_ATTRMAP 128
34 
35 typedef enum {
36  CACHE_RECONNECT = -2, //!< Handle needs to be reconnected
37  CACHE_ERROR = -1, //!< Fatal error
38  CACHE_OK = 0, //!< Cache entry found/updated
39  CACHE_MISS = 1 //!< Cache entry notfound
41 
42 /** Configuration for the rlm_cache module
43  *
44  * This is separate from the #rlm_cache_t struct, to limit driver's visibility of
45  * rlm_cache instance data.
46  */
47 typedef struct rlm_cache_config_t {
48  char const *name; //!< Name of xlat function to register.
49  char const *driver_name; //!< Driver name.
50  vp_tmpl_t *key; //!< What to expand to get the value of the key.
51  uint32_t ttl; //!< How long an entry is valid for.
52  uint32_t max_entries; //!< Maximum entries allowed.
53  int32_t epoch; //!< Time after which entries are considered valid.
54  bool stats; //!< Generate statistics.
56 
57 /*
58  * Define a structure for our module configuration.
59  *
60  * These variables do not need to be in a structure, but it's
61  * a lot cleaner to do so, and a pointer to the structure can
62  * be used as the instance handle.
63  */
64 typedef struct rlm_cache_t {
65  rlm_cache_config_t config; //!< Must come first because of icky hacks.
66 
67  void *handle; //!< Driver handle.
68  cache_driver_t *driver; //!< Driver.
69  void *driver_inst; //!< Driver instance data.
70 
71  vp_map_t *maps; //!< Attribute map applied to users.
72  //!< and profiles.
74 } rlm_cache_t;
75 
76 typedef struct rlm_cache_entry_t {
77  uint8_t const *key; //!< Key used to identify entry.
78  size_t key_len; //!< Length of key data.
79  long long int hits; //!< How many times the entry has been retrieved.
80  time_t created; //!< When the entry was created.
81  time_t expires; //!< When the entry expires.
82 
83  vp_map_t *maps; //!< Head of the maps list.
85 
86 /** Instantiate a driver
87  *
88  * Function to handle any driver specific instantiation.
89  *
90  * @param conf section holding driver specific #CONF_PAIR (s).
91  * @param config of the rlm_cache module. Should not be modified.
92  * @param driver_inst A uint8_t array of inst_size if inst_size > 0, else NULL.
93  * Drivers should add their own cleanup function to this chunk using talloc_set_destructor.
94  * @return
95  * - 0 on success.
96  * - -1 on failure.
97  */
98 typedef int (*cache_instantiate_t)(CONF_SECTION *conf, rlm_cache_config_t const *config, void *driver_inst);
99 
100 /** Allocate a new cache entry
101  *
102  */
103 typedef rlm_cache_entry_t *(*cache_entry_alloc_t)(rlm_cache_config_t const *conf, void *driver_inst, REQUEST *request);
104 
105 /** Free a cache entry
106  *
107  * @note This callback is optional, but the driver assume responsibility for freeing the
108  * cache_entry_t on #cache_entry_expire_t.
109  *
110  * If the driver does not need to keep a local copy of the cache entry, it should provide
111  * a callback to free the memory previously allocated for the cache entry by
112  * #cache_entry_find_t or by rlm_cache.
113  *
114  * @param c entry to free.
115  */
117 
118 /** Retrieve an entry from the cache
119  *
120  * If a cache entry is found, but the cache entry needs to be deserialized, the driver
121  * is expected to allocate an appropriately sized #rlm_cache_entry_t, perform the deserialisation,
122  * and write a pointer to the new entry to out, returning #CACHE_OK.
123  *
124  * If the #rlm_cache_handle_t is inviable, the driver should return #CACHE_RECONNECT, to have
125  * it reinitialised/reconnected.
126  *
127  * @param[out] out Where to write a pointer to the retrieved entry (if there was one).
128  * @param[in] config for this instance of the rlm_cache module.
129  * @param[in] driver_inst Driver specific instance data.
130  * @param[in] request The current request.
131  * @param[in] handle the driver gave us when we called #cache_acquire_t, or NULL if no
132  * #cache_acquire_t callback was provided.
133  * @param[in] key to use to lookup cache entry
134  * @param[in] key_len the length of the key string.
135  * @return
136  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
137  * - #CACHE_ERROR - If the lookup couldn't be completed.
138  * - #CACHE_OK - Lookup was successful.
139  * - #CACHE_MISS - No cached entry was found.
140  */
142  void *driver_inst, REQUEST *request, void *handle,
143  uint8_t const *key, size_t key_len);
144 
145 /** Insert an entry into the cache
146  *
147  * Serialize (if necessary) the entry passed to us, and write it to the cache with
148  * the key c->key.
149  *
150  * The cache entry should not be freed by the driver, irrespective of success or failure.
151  * If the entry needs to be freed after insertion because a local copy should not be kept,
152  * the driver should provide a #cache_entry_free_t callback.
153  *
154  * If the #rlm_cache_handle_t is inviable, the driver should return #CACHE_RECONNECT, to have
155  * it reinitialised/reconnected.
156  *
157  * @note This callback is not optional.
158  *
159  * @note This callback *must* overwrite existing cache entries on insert.
160  *
161  * @param config for this instance of the rlm_cache module.
162  * @param driver_inst Driver specific instance data.
163  * @param request The current request.
164  * @param handle the driver gave us when we called #cache_acquire_t, or NULL if no
165  * #cache_acquire_t callback was provided.
166  * @param c to insert.
167  * @return
168  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
169  * - #CACHE_ERROR - If the insert couldn't be completed.
170  * - #CACHE_OK - If the insert was successful.
171  */
172 typedef cache_status_t (*cache_entry_insert_t)(rlm_cache_config_t const *config, void *driver_inst,
173  REQUEST *request, void *handle,
174  rlm_cache_entry_t const *c);
175 
176 /** Remove an entry from the cache
177  *
178  * @note This callback is not optional.
179  *
180  * @param[in] config for this instance of the rlm_cache module.
181  * @param[in] driver_inst Driver specific instance data.
182  * @param[in] request The current request.
183  * @param[in] handle the driver gave us when we called #cache_acquire_t, or NULL if no
184  * #cache_acquire_t callback was provided.
185  * @param[in] key of entry to expire.
186  * @param[in] key_len the length of the key string.
187  * @return
188  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
189  * - #CACHE_ERROR - If the entry couldn't be expired.
190  * - #CACHE_OK - If the entry was expired.
191  * - #CACHE_MISS - If the entry didn't exist, so couldn't be expired.
192  */
193 typedef cache_status_t (*cache_entry_expire_t)(rlm_cache_config_t const *config, void *driver_inst,
194  REQUEST *request, void *handle,
195  uint8_t const *key, size_t key_len);
196 
197 /** Update the ttl of an entry in the cace
198  *
199  * @note This callback optional. If it's not specified the cache code will expire and
200  * recreate the entry with a new TTL.
201  *
202  * If the #rlm_cache_handle_t is inviable, the driver should return #CACHE_RECONNECT, to have
203  * it reinitialised/reconnected.
204  *
205  * @param[in] config for this instance of the rlm_cache module.
206  * @param[in] driver_inst Driver specific instance data.
207  * @param[in] request The current request.
208  * @param[in] handle the driver gave us when we called #cache_acquire_t, or NULL if no
209  * #cache_acquire_t callback was provided.
210  * @param[in] c to update the TTL of. c->ttl will have been set to the new value.
211  * @return
212  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
213  * - #CACHE_ERROR - If the entry TTL couldn't be updated.
214  * - #CACHE_OK - If the entry's TTL was updated.
215  */
216 typedef cache_status_t (*cache_entry_set_ttl_t)(rlm_cache_config_t const *config, void *driver_inst,
217  REQUEST *request, void *handle,
218  rlm_cache_entry_t *c);
219 
220 /** Get the number of entries in the cache
221  *
222  * @note This callback is optional. Though max_entries will not be enforced if it is not provided.
223  *
224  * @param[in] config for this instance of the rlm_cache module.
225  * @param[in] driver_inst Driver specific instance data.
226  * @param[in] request The current request.
227  * @param handle the driver gave us when we called #cache_acquire_t, or NULL if no
228  * #cache_acquire_t callback was provided.
229  * @return number of entries in the cache.
230  */
231 typedef uint32_t (*cache_entry_count_t)(rlm_cache_config_t const *config, void *driver_inst,
232  REQUEST *request, void *handle);
233 
234 /** Acquire a handle to access the cache
235  *
236  * @note This callback is optional. If it's not provided the handle argument to other callbacks
237  * will be NULL.
238  *
239  * @param[out] handle Where to write pointer to handle to access the cache with.
240  * @param[in] config for this instance of the rlm_cache module.
241  * @param[in] driver_inst Driver specific instance data.
242  * @param[in] request The current request.
243  * @return
244  * - 0 on success.
245  * - -1 on failure.
246  */
247 typedef int (*cache_acquire_t)(void **handle, rlm_cache_config_t const *config, void *driver_inst,
248  REQUEST *request);
249 
250 /** Release a previously acquired handle
251  *
252  * @note This callback is optional.
253  *
254  * @param[in] config for this instance of the rlm_cache module.
255  * @param[in] driver_inst Driver specific instance data.
256  * @param[in] request The current request.
257  * @param[in] handle to release.
258  */
259 typedef void (*cache_release_t)(rlm_cache_config_t const *config, void *driver_inst, REQUEST *request,
260  rlm_cache_handle_t *handle);
261 
262 /** Reconnect a previously acquired handle
263  *
264  * @note This callback is optional.
265  *
266  * @param[in,out] handle to reinitialise/reconnect.
267  * @param[in] config for this instance of the rlm_cache module.
268  * @param[in] driver_inst Driver specific instance data.
269  * @param[in] request The current request.
270 
271  * @return
272  * - 0 on success.
273  * - -1 on failure.
274  */
275 typedef int (*cache_reconnect_t)(rlm_cache_handle_t **handle, rlm_cache_config_t const *config,
276  void *driver_inst, REQUEST *request);
277 
278 struct cache_driver {
279  char const *name; //!< Driver name.
280 
281  cache_instantiate_t instantiate; //!< (optional) Instantiate a driver.
282  cache_entry_alloc_t alloc; //!< (optional) Allocate a new entry.
283  cache_entry_free_t free; //!< (optional) Free memory used by an entry.
284 
285  cache_entry_find_t find; //!< Retrieve an existing cache entry.
286  cache_entry_insert_t insert; //!< Add a new entry.
287  cache_entry_expire_t expire; //!< Remove an old entry.
288  cache_entry_set_ttl_t set_ttl; //!< (Optional) Update the TTL of an entry.
289  cache_entry_count_t count; //!< (Optional) Number of entries currently in
290  //!< the cache.
291 
292  cache_acquire_t acquire; //!< (optional) Acquire exclusive access to a resource
293  //!< used to retrieve the cache entry.
294  cache_release_t release; //!< (optional) Release access to resource acquired
295  //!< with acquire callback.
296  cache_reconnect_t reconnect; //!< (optional) Re-initialise resource.
297 
298  size_t inst_size; //!< How many bytes should be allocated for the driver's
299  //!< instance data.
300 };
uint32_t(* cache_entry_count_t)(rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, void *handle)
Get the number of entries in the cache.
Definition: rlm_cache.h:231
Definition: rlm_cache.h:76
#define RCSIDH(h, id)
Definition: build.h:136
cache_driver_t * driver
Driver.
Definition: rlm_cache.h:68
Fatal error.
Definition: rlm_cache.h:37
Cache entry notfound.
Definition: rlm_cache.h:39
int(* cache_reconnect_t)(rlm_cache_handle_t **handle, rlm_cache_config_t const *config, void *driver_inst, REQUEST *request)
Reconnect a previously acquired handle.
Definition: rlm_cache.h:275
cache_acquire_t acquire
(optional) Acquire exclusive access to a resource used to retrieve the cache entry.
Definition: rlm_cache.h:292
cache_entry_insert_t insert
Add a new entry.
Definition: rlm_cache.h:286
cache_reconnect_t reconnect
(optional) Re-initialise resource.
Definition: rlm_cache.h:296
vp_tmpl_t * key
What to expand to get the value of the key.
Definition: rlm_cache.h:50
int32_t epoch
Time after which entries are considered valid.
Definition: rlm_cache.h:53
uint32_t max_entries
Maximum entries allowed.
Definition: rlm_cache.h:52
struct rlm_cache_t rlm_cache_t
Handle needs to be reconnected.
Definition: rlm_cache.h:36
rlm_cache_config_t config
Must come first because of icky hacks.
Definition: rlm_cache.h:65
uint32_t ttl
How long an entry is valid for.
Definition: rlm_cache.h:51
bool stats
Generate statistics.
Definition: rlm_cache.h:54
cache_status_t
Definition: rlm_cache.h:35
struct rlm_cache_entry_t rlm_cache_entry_t
cache_status_t(* cache_entry_insert_t)(rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, void *handle, rlm_cache_entry_t const *c)
Insert an entry into the cache.
Definition: rlm_cache.h:172
cache_release_t release
(optional) Release access to resource acquired with acquire callback.
Definition: rlm_cache.h:294
size_t key_len
Length of key data.
Definition: rlm_cache.h:78
rlm_cache_entry_t *(* cache_entry_alloc_t)(rlm_cache_config_t const *conf, void *driver_inst, REQUEST *request)
Allocate a new cache entry.
Definition: rlm_cache.h:103
time_t expires
When the entry expires.
Definition: rlm_cache.h:81
cache_entry_alloc_t alloc
(optional) Allocate a new entry.
Definition: rlm_cache.h:282
vp_map_t * maps
Attribute map applied to users.
Definition: rlm_cache.h:71
cache_entry_free_t free
(optional) Free memory used by an entry.
Definition: rlm_cache.h:283
long long int hits
How many times the entry has been retrieved.
Definition: rlm_cache.h:79
void rlm_cache_handle_t
Definition: rlm_cache.h:31
int(* cache_instantiate_t)(CONF_SECTION *conf, rlm_cache_config_t const *config, void *driver_inst)
Instantiate a driver.
Definition: rlm_cache.h:98
static rs_t * conf
Definition: radsniff.c:46
cache_entry_set_ttl_t set_ttl
(Optional) Update the TTL of an entry.
Definition: rlm_cache.h:288
time_t created
When the entry was created.
Definition: rlm_cache.h:80
cache_entry_expire_t expire
Remove an old entry.
Definition: rlm_cache.h:287
cache_entry_count_t count
(Optional) Number of entries currently in the cache.
Definition: rlm_cache.h:289
cache_status_t(* cache_entry_expire_t)(rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, void *handle, uint8_t const *key, size_t key_len)
Remove an entry from the cache.
Definition: rlm_cache.h:193
int(* cache_acquire_t)(void **handle, rlm_cache_config_t const *config, void *driver_inst, REQUEST *request)
Acquire a handle to access the cache.
Definition: rlm_cache.h:247
Cache entry found/updated.
Definition: rlm_cache.h:38
char const * name
Name of xlat function to register.
Definition: rlm_cache.h:48
CONF_SECTION * cs
Definition: rlm_cache.h:73
char const * driver_name
Driver name.
Definition: rlm_cache.h:49
cache_status_t(* cache_entry_find_t)(rlm_cache_entry_t **out, rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, void *handle, uint8_t const *key, size_t key_len)
Retrieve an entry from the cache.
Definition: rlm_cache.h:141
void * handle
Driver handle.
Definition: rlm_cache.h:67
void(* cache_release_t)(rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, rlm_cache_handle_t *handle)
Release a previously acquired handle.
Definition: rlm_cache.h:259
void * driver_inst
Driver instance data.
Definition: rlm_cache.h:69
cache_status_t(* cache_entry_set_ttl_t)(rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, void *handle, rlm_cache_entry_t *c)
Update the ttl of an entry in the cace.
Definition: rlm_cache.h:216
struct rlm_cache_config_t rlm_cache_config_t
Configuration for the rlm_cache module.
cache_entry_find_t find
Retrieve an existing cache entry.
Definition: rlm_cache.h:285
cache_instantiate_t instantiate
(optional) Instantiate a driver.
Definition: rlm_cache.h:281
vp_map_t * maps
Head of the maps list.
Definition: rlm_cache.h:83
char const * name
Driver name.
Definition: rlm_cache.h:279
void(* cache_entry_free_t)(rlm_cache_entry_t *c)
Free a cache entry.
Definition: rlm_cache.h:116
size_t inst_size
How many bytes should be allocated for the driver's instance data.
Definition: rlm_cache.h:298
uint8_t const * key
Key used to identify entry.
Definition: rlm_cache.h:77
Value pair map.
Definition: map.h:46
A source or sink of value data.
Definition: tmpl.h:187
Configuration for the rlm_cache module.
Definition: rlm_cache.h:47