The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
rlm_cache.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: 7915bb91ec36f02cb9e12c7cc4809c282a3c33b1 $
20  * @file rlm_cache.h
21  * @brief Cache values and merge them back into future requests.
22  *
23  * @copyright 2014 The FreeRADIUS server project
24  * @copyright 2014 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25  */
26 RCSIDH(cache_h, "$Id: 7915bb91ec36f02cb9e12c7cc4809c282a3c33b1 $")
27 
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/server/dl_module.h>
30 #include <freeradius-devel/server/map.h>
31 #include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
32 
34 
35 typedef void rlm_cache_handle_t;
36 
37 #define MAX_ATTRMAP 128
38 
39 typedef enum {
40  CACHE_RECONNECT = -2, //!< Handle needs to be reconnected
41  CACHE_ERROR = -1, //!< Fatal error
42  CACHE_OK = 0, //!< Cache entry found/updated
43  CACHE_MISS = 1 //!< Cache entry notfound
45 
46 /** Configuration for the rlm_cache module
47  *
48  * This is separate from the #rlm_cache_t struct, to limit driver's visibility of
49  * rlm_cache instance data.
50  */
51 typedef struct {
52  fr_time_delta_t ttl; //!< How long an entry is valid for.
53  uint32_t max_entries; //!< Maximum entries allowed.
54  int32_t epoch; //!< Time after which entries are considered valid.
55  bool stats; //!< Generate statistics.
57 
58 /*
59  * Define a structure for our module configuration.
60  *
61  * These variables do not need to be in a structure, but it's
62  * a lot cleaner to do so, and a pointer to the structure can
63  * be used as the instance handle.
64  */
65 typedef struct {
66  rlm_cache_config_t config; //!< Must come first because of icky hacks.
67 
68  module_instance_t *driver_submodule; //!< Driver's instance data.
69  rlm_cache_driver_t const *driver; //!< Driver's exported interface.
70 } rlm_cache_t;
71 
72 typedef struct {
73  fr_value_box_t key; //!< Key used to identify entry.
74  long long int hits; //!< How many times the entry has been retrieved.
75  fr_unix_time_t created; //!< When the entry was created.
76  fr_unix_time_t expires; //!< When the entry expires.
77 
78  map_list_t maps; //!< Head of the maps list.
80 
81 /** Allocate a new cache entry
82  *
83  */
84 typedef rlm_cache_entry_t *(*cache_entry_alloc_t)(rlm_cache_config_t const *config, void *instance, request_t *request);
85 
86 /** Free a cache entry
87  *
88  * @note This callback is optional, but the driver assume responsibility for freeing the
89  * cache_entry_t on #cache_entry_expire_t.
90  *
91  * If the driver does not need to keep a local copy of the cache entry, it should provide
92  * a callback to free the memory previously allocated for the cache entry by
93  * #cache_entry_find_t or by rlm_cache.
94  *
95  * @param c entry to free.
96  */
98 
99 /** Retrieve an entry from the cache
100  *
101  * If a cache entry is found, but the cache entry needs to be deserialized, the driver
102  * is expected to allocate an appropriately sized #rlm_cache_entry_t, perform the deserialisation,
103  * and write a pointer to the new entry to out, returning #CACHE_OK.
104  *
105  * If the #rlm_cache_handle_t is inviable, the driver should return #CACHE_RECONNECT, to have
106  * it reinitialised/reconnected.
107  *
108  * @param[out] out Where to write a pointer to the retrieved entry (if there was one).
109  * @param[in] config for this instance of the rlm_cache module.
110  * @param[in] instance Driver specific instance data.
111  * @param[in] request The current request.
112  * @param[in] handle the driver gave us when we called #cache_acquire_t, or NULL if no
113  * #cache_acquire_t callback was provided.
114  * @param[in] key to use to lookup cache entry
115  * @return
116  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
117  * - #CACHE_ERROR - If the lookup couldn't be completed.
118  * - #CACHE_OK - Lookup was successful.
119  * - #CACHE_MISS - No cached entry was found.
120  */
122  void *instance, request_t *request, void *handle,
123  fr_value_box_t const *key);
124 
125 /** Insert an entry into the cache
126  *
127  * Serialize (if necessary) the entry passed to us, and write it to the cache with
128  * the key c->key.
129  *
130  * The cache entry should not be freed by the driver, irrespective of success or failure.
131  * If the entry needs to be freed after insertion because a local copy should not be kept,
132  * the driver should provide a #cache_entry_free_t callback.
133  *
134  * If the #rlm_cache_handle_t is inviable, the driver should return #CACHE_RECONNECT, to have
135  * it reinitialised/reconnected.
136  *
137  * @note This callback is not optional.
138  *
139  * @note This callback *must* overwrite existing cache entries on insert.
140  *
141  * @param config for this instance of the rlm_cache module.
142  * @param instance Driver specific instance data.
143  * @param request The current request.
144  * @param handle the driver gave us when we called #cache_acquire_t, or NULL if no
145  * #cache_acquire_t callback was provided.
146  * @param c to insert.
147  * @return
148  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
149  * - #CACHE_ERROR - If the insert couldn't be completed.
150  * - #CACHE_OK - If the insert was successful.
151  */
153  request_t *request, void *handle,
154  rlm_cache_entry_t const *c);
155 
156 /** Remove an entry from the cache
157  *
158  * @note This callback is not optional.
159  *
160  * @param[in] config for this instance of the rlm_cache module.
161  * @param[in] instance Driver specific instance data.
162  * @param[in] request The current request.
163  * @param[in] handle the driver gave us when we called #cache_acquire_t, or NULL if no
164  * #cache_acquire_t callback was provided.
165  * @param[in] key of entry to expire.
166  * @return
167  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
168  * - #CACHE_ERROR - If the entry couldn't be expired.
169  * - #CACHE_OK - If the entry was expired.
170  * - #CACHE_MISS - If the entry didn't exist, so couldn't be expired.
171  */
173  request_t *request, void *handle,
174  fr_value_box_t const *key);
175 
176 /** Update the ttl of an entry in the cache
177  *
178  * @note This callback optional. If it's not specified the cache code will expire and
179  * recreate the entry with a new TTL.
180  *
181  * If the #rlm_cache_handle_t is inviable, the driver should return #CACHE_RECONNECT, to have
182  * it reinitialised/reconnected.
183  *
184  * @param[in] config for this instance of the rlm_cache module.
185  * @param[in] instance Driver specific instance data.
186  * @param[in] request The current request.
187  * @param[in] handle the driver gave us when we called #cache_acquire_t, or NULL if no
188  * #cache_acquire_t callback was provided.
189  * @param[in] c to update the TTL of. c->ttl will have been set to the new value.
190  * @return
191  * - #CACHE_RECONNECT - If handle needs to be reinitialised/reconnected.
192  * - #CACHE_ERROR - If the entry TTL couldn't be updated.
193  * - #CACHE_OK - If the entry's TTL was updated.
194  */
196  request_t *request, void *handle,
197  rlm_cache_entry_t *c);
198 
199 /** Get the number of entries in the cache
200  *
201  * @note This callback is optional. Though max_entries will not be enforced if it is not provided.
202  *
203  * @param[in] config for this instance of the rlm_cache module.
204  * @param[in] instance Driver specific instance data.
205  * @param[in] request The current request.
206  * @param handle the driver gave us when we called #cache_acquire_t, or NULL if no
207  * #cache_acquire_t callback was provided.
208  * @return number of entries in the cache.
209  */
210 typedef uint64_t (*cache_entry_count_t)(rlm_cache_config_t const *config, void *instance,
211  request_t *request, void *handle);
212 
213 /** Acquire a handle to access the cache
214  *
215  * @note This callback is optional. If it's not provided the handle argument to other callbacks
216  * will be NULL.
217  *
218  * @param[out] handle Where to write pointer to handle to access the cache with.
219  * @param[in] config for this instance of the rlm_cache module.
220  * @param[in] instance Driver specific instance data.
221  * @param[in] request The current request.
222  * @return
223  * - 0 on success.
224  * - -1 on failure.
225  */
226 typedef int (*cache_acquire_t)(void **handle, rlm_cache_config_t const *config, void *instance,
227  request_t *request);
228 
229 /** Release a previously acquired handle
230  *
231  * @note This callback is optional.
232  *
233  * @param[in] config for this instance of the rlm_cache module.
234  * @param[in] instance Driver specific instance data.
235  * @param[in] request The current request.
236  * @param[in] handle to release.
237  */
238 typedef void (*cache_release_t)(rlm_cache_config_t const *config, void *instance, request_t *request,
239  rlm_cache_handle_t *handle);
240 
241 /** Reconnect a previously acquired handle
242  *
243  * @note This callback is optional.
244  *
245  * @param[in,out] handle to reinitialise/reconnect.
246  * @param[in] config for this instance of the rlm_cache module.
247  * @param[in] instance Driver specific instance data.
248  * @param[in] request The current request.
249 
250  * @return
251  * - 0 on success.
252  * - -1 on failure.
253  */
255  void *instance, request_t *request);
256 
258  module_t common; //!< Common fields for all loadable modules.
259 
260  cache_entry_alloc_t alloc; //!< (optional) Allocate a new entry.
261  cache_entry_free_t free; //!< (optional) Free memory used by an entry.
262 
263  cache_entry_find_t find; //!< Retrieve an existing cache entry.
264  cache_entry_insert_t insert; //!< Add a new entry.
265  cache_entry_expire_t expire; //!< Remove an old entry.
266  cache_entry_set_ttl_t set_ttl; //!< (Optional) Update the TTL of an entry.
267  cache_entry_count_t count; //!< (Optional) Number of entries currently in
268  //!< the cache.
269 
270  cache_acquire_t acquire; //!< (optional) Acquire exclusive access to a resource
271  //!< used to retrieve the cache entry.
272  cache_release_t release; //!< (optional) Release access to resource acquired
273  //!< with acquire callback.
274  cache_reconnect_t reconnect; //!< (optional) Re-initialise resource.
275 
276  call_env_parse_pair_t key_parse; //!< (optional) custom key parser. Allows the driver
277  ///< to have complete control over how the key is
278  ///< parsed. If not provided, the default key parser
279  ///< will be used. data will be set to the submodule's
280  ///< instance data, NOT the #rlm_cache_t.
281 };
#define RCSIDH(h, id)
Definition: build.h:482
int(* call_env_parse_pair_t)(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, call_env_ctx_t const *cec, call_env_parser_t const *rule)
Callback for performing custom parsing of a CONF_PAIR.
Definition: call_env.h:146
unsigned int uint32_t
Definition: merged_model.c:33
static const conf_parser_t config[]
Definition: base.c:183
rlm_cache_entry_t *(* cache_entry_alloc_t)(rlm_cache_config_t const *config, void *instance, request_t *request)
Allocate a new cache entry.
Definition: rlm_cache.h:84
uint32_t max_entries
Maximum entries allowed.
Definition: rlm_cache.h:53
cache_entry_find_t find
Retrieve an existing cache entry.
Definition: rlm_cache.h:263
int32_t epoch
Time after which entries are considered valid.
Definition: rlm_cache.h:54
cache_entry_insert_t insert
Add a new entry.
Definition: rlm_cache.h:264
module_instance_t * driver_submodule
Driver's instance data.
Definition: rlm_cache.h:68
cache_status_t(* cache_entry_set_ttl_t)(rlm_cache_config_t const *config, void *instance, request_t *request, void *handle, rlm_cache_entry_t *c)
Update the ttl of an entry in the cache.
Definition: rlm_cache.h:195
fr_time_delta_t ttl
How long an entry is valid for.
Definition: rlm_cache.h:52
cache_entry_expire_t expire
Remove an old entry.
Definition: rlm_cache.h:265
cache_status_t(* cache_entry_insert_t)(rlm_cache_config_t const *config, void *instance, request_t *request, void *handle, rlm_cache_entry_t const *c)
Insert an entry into the cache.
Definition: rlm_cache.h:152
cache_entry_set_ttl_t set_ttl
(Optional) Update the TTL of an entry.
Definition: rlm_cache.h:266
bool stats
Generate statistics.
Definition: rlm_cache.h:55
cache_entry_alloc_t alloc
(optional) Allocate a new entry.
Definition: rlm_cache.h:260
fr_value_box_t key
Key used to identify entry.
Definition: rlm_cache.h:73
map_list_t maps
Head of the maps list.
Definition: rlm_cache.h:78
uint64_t(* cache_entry_count_t)(rlm_cache_config_t const *config, void *instance, request_t *request, void *handle)
Get the number of entries in the cache.
Definition: rlm_cache.h:210
fr_unix_time_t created
When the entry was created.
Definition: rlm_cache.h:75
rlm_cache_config_t config
Must come first because of icky hacks.
Definition: rlm_cache.h:66
void(* cache_entry_free_t)(rlm_cache_entry_t *c)
Free a cache entry.
Definition: rlm_cache.h:97
int(* cache_reconnect_t)(rlm_cache_handle_t **handle, rlm_cache_config_t const *config, void *instance, request_t *request)
Reconnect a previously acquired handle.
Definition: rlm_cache.h:254
rlm_cache_driver_t const * driver
Driver's exported interface.
Definition: rlm_cache.h:69
long long int hits
How many times the entry has been retrieved.
Definition: rlm_cache.h:74
cache_release_t release
(optional) Release access to resource acquired with acquire callback.
Definition: rlm_cache.h:272
cache_entry_free_t free
(optional) Free memory used by an entry.
Definition: rlm_cache.h:261
void(* cache_release_t)(rlm_cache_config_t const *config, void *instance, request_t *request, rlm_cache_handle_t *handle)
Release a previously acquired handle.
Definition: rlm_cache.h:238
cache_entry_count_t count
(Optional) Number of entries currently in the cache.
Definition: rlm_cache.h:267
int(* cache_acquire_t)(void **handle, rlm_cache_config_t const *config, void *instance, request_t *request)
Acquire a handle to access the cache.
Definition: rlm_cache.h:226
module_t common
Common fields for all loadable modules.
Definition: rlm_cache.h:258
cache_status_t
Definition: rlm_cache.h:39
@ CACHE_ERROR
Fatal error.
Definition: rlm_cache.h:41
@ CACHE_RECONNECT
Handle needs to be reconnected.
Definition: rlm_cache.h:40
@ CACHE_OK
Cache entry found/updated.
Definition: rlm_cache.h:42
@ CACHE_MISS
Cache entry notfound.
Definition: rlm_cache.h:43
cache_reconnect_t reconnect
(optional) Re-initialise resource.
Definition: rlm_cache.h:274
call_env_parse_pair_t key_parse
(optional) custom key parser.
Definition: rlm_cache.h:276
void rlm_cache_handle_t
Definition: rlm_cache.h:35
fr_unix_time_t expires
When the entry expires.
Definition: rlm_cache.h:76
cache_status_t(* cache_entry_find_t)(rlm_cache_entry_t **out, rlm_cache_config_t const *config, void *instance, request_t *request, void *handle, fr_value_box_t const *key)
Retrieve an entry from the cache.
Definition: rlm_cache.h:121
cache_acquire_t acquire
(optional) Acquire exclusive access to a resource used to retrieve the cache entry.
Definition: rlm_cache.h:270
cache_status_t(* cache_entry_expire_t)(rlm_cache_config_t const *config, void *instance, request_t *request, void *handle, fr_value_box_t const *key)
Remove an entry from the cache.
Definition: rlm_cache.h:172
Configuration for the rlm_cache module.
Definition: rlm_cache.h:51
Definition: rlm_cache.h:72
Module instance data.
Definition: module.h:265
Struct exported by a rlm_* module.
Definition: module.h:195
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
"Unix" time.
Definition: time.h:95
static size_t char ** out
Definition: value.h:997