]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Dynamically resolve dictionary entrys for control attrs
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 16 Jan 2013 19:44:17 +0000 (19:44 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 16 Jan 2013 19:44:17 +0000 (19:44 +0000)
Add control:Cache-Merge, when set to no makes the cache 'wo'

share/dictionary.freeradius.internal
src/include/radius.h
src/modules/rlm_cache/rlm_cache.c

index 5f546628ec5750d4349d237e92511c9395dccc92..652ebeead641a57ccbaf9d6880e717f5981e77f9 100644 (file)
@@ -224,11 +224,15 @@ ATTRIBUTE Stripped-User-Domain                    1138    string
 ATTRIBUTE      Called-Station-SSID                     1139    string
 ATTRIBUTE      Cache-TTL                               1140    integer
 ATTRIBUTE      Cache-Status-Only                       1141    integer
-ATTRIBUTE      Cache-Entry-Hits                        1142    integer
+ATTRIBUTE      Cache-Merge                             1142    integer
+ATTRIBUTE      Cache-Entry-Hits                        1143    integer
 
 VALUE  Cache-Status-Only               no                      0
 VALUE  Cache-Status-Only               yes                     1
 
+VALUE  Cache-Merge                     no                      0
+VALUE  Cache-Merge                     yes                     1
+
 #      More dynamic client attributes
 
 ATTRIBUTE      FreeRADIUS-Client-Src-IP-Address        1143    ipaddr
index c7a48161e93f0f45bf4484478cd1100921b32bd1..3660248f6bc5c88d4e842ec16e2af5a93046b539 100644 (file)
 #define PW_MSCHAP_PASSWORD             1133
 #define PW_PACKET_TRANSMIT_COUNTER     1134
 #define PW_CACHED_SESSION_POLICY       1135
-#define PW_CACHE_TTL                   1140
-#define PW_CACHE_STATUS_ONLY           1141
-#define PW_CACHE_ENTRY_HITS            1142
 #define PW_FREERADIUS_CLIENT_SRC_IP_ADDRESS    1143
 #define PW_FREERADIUS_CLIENT_SRC_IPV6_ADDRESS  1144
 
index 471e31b589da318e074cc373c0bb9ad8ca65131c..f02023eb79adfc8f17166de193fc7f77ef5327b4 100644 (file)
@@ -47,6 +47,19 @@ typedef struct rlm_cache_t {
        
        value_pair_map_t        *maps;  //!< Attribute map applied to users 
                                        //!< and profiles.
+                                       
+       DICT_ATTR               *cache_ttl;         //!< Control attribute,
+                                                   //!< modifies cache TTL at
+                                                   //!< runtime.
+       DICT_ATTR               *cache_status_only; //!< Control attribute,
+                                                   //!< modifies cache 
+                                                   //!< behaviour at runtime.
+       DICT_ATTR               *cache_merge;       //!< Control attribute,
+                                                   //!< modifies cache
+                                                   //!< behaviour at runtime.
+       DICT_ATTR               *cache_entry_hits;  //!< Attribute showing the
+                                                   //!< number of hits on the
+                                                   //!< cache entry.
 #ifdef HAVE_PTHREAD_H
        pthread_mutex_t cache_mutex;
 #endif
@@ -121,6 +134,15 @@ static void cache_merge(rlm_cache_t *inst, REQUEST *request,
 
        rad_assert(request != NULL);
        rad_assert(c != NULL);
+       
+       vp = pairfind(request->config_items,
+                     inst->cache_merge->attr, 
+                     inst->cache_merge->vendor,
+                     TAG_ANY);
+       if (vp && (vp->vp_integer == 0)) {
+               RDEBUG2("Told not to merge entry into request");
+               return;
+       }
 
        if (c->control) {
                RDEBUG2("Merging cached control list:");
@@ -150,7 +172,7 @@ static void cache_merge(rlm_cache_t *inst, REQUEST *request,
        }
        
        if (inst->stats) {
-               vp = paircreate(PW_CACHE_ENTRY_HITS, 0, PW_TYPE_INTEGER);
+               vp = pairalloc(inst->cache_entry_hits);
                rad_assert(vp != NULL);
                
                vp->vp_integer = c->hits;
@@ -215,7 +237,10 @@ static rlm_cache_entry_t *cache_find(rlm_cache_t *inst, REQUEST *request,
         *      Update the expiry time based on the TTL.
         *      A TTL of 0 means "delete from the cache".
         */
-       vp = pairfind(request->config_items, PW_CACHE_TTL, 0, TAG_ANY);
+       vp = pairfind(request->config_items,
+                     inst->cache_ttl->attr,
+                     inst->cache_ttl->vendor,
+                     TAG_ANY);
        if (vp) {
                if (vp->vp_integer == 0) goto delete;
                
@@ -239,6 +264,7 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
        VALUE_PAIR *vp, *found, **to_req, **to_cache, **from;
        const DICT_ATTR *da;
 
+       int merge = TRUE;
        REQUEST *context;
 
        const value_pair_map_t *map;
@@ -249,12 +275,14 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
        /*
         *      TTL of 0 means "don't cache this entry"
         */
-       vp = pairfind(request->config_items, PW_CACHE_TTL, 0, TAG_ANY);
+       vp = pairfind(request->config_items,
+                     inst->cache_ttl->attr,
+                     inst->cache_ttl->vendor,
+                     TAG_ANY);
+                     
        if (vp && (vp->vp_integer == 0)) return NULL;
 
-       c = rad_malloc(sizeof(*c));
-       memset(c, 0, sizeof(*c));
-
+       c = rad_calloc(sizeof(*c));
        c->key = strdup(key);
        c->created = c->expires = request->timestamp;
 
@@ -270,8 +298,19 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
 
        RDEBUG("Creating entry for \"%s\"", key);
        
-       for (map = inst->maps; map != NULL; map = map->next)
-       {
+       /*
+        *      Check to see if we need to merge the entry into the request
+        */
+       vp = pairfind(request->config_items,
+                     inst->cache_merge->attr, 
+                     inst->cache_merge->vendor,
+                     TAG_ANY);
+       if (vp && (vp->vp_integer == 0)) {
+               merge = FALSE;
+               RDEBUG2("Told not to merge new entry into request");
+       }
+       
+       for (map = inst->maps; map != NULL; map = map->next) {
                rad_assert(map->dst && map->src);
 
                /* 
@@ -307,9 +346,9 @@ static rlm_cache_entry_t *cache_add(rlm_cache_t *inst, REQUEST *request,
                 *        - Map src and dst attributes differ
                 */
                to_req = NULL;
-               if (!map->src->da || (map->src->list != map->dst->list) ||
-                   (map->src->da != map->dst->da))
-               {
+               if (!merge || !map->src->da || 
+                   (map->src->list != map->dst->list) ||
+                   (map->src->da != map->dst->da)) {
                        context = request;
                        /*
                         *      It's ok if the list isn't valid here...
@@ -696,7 +735,20 @@ static int cache_instantiate(CONF_SECTION *conf, void **instance)
        rlm_cache_t *inst;
 
        inst = rad_calloc(sizeof(*inst));
-       inst->cs = conf;        
+       inst->cs = conf;
+       
+       /*
+        *      The right way to resolve attribute numbers
+        */
+       if (!(
+            (inst->cache_ttl = dict_attrbyname("Cache-TTL")) &&
+            (inst->cache_status_only = dict_attrbyname("Cache-Status-Only")) &&
+            (inst->cache_merge = dict_attrbyname("Cache-Merge")) &&
+            (inst->cache_entry_hits = dict_attrbyname("Cache-Entry-Hits")))) {
+               radlog(L_ERR, "rlm_cache: Failed resolving dictionary "
+                      "attributes, check dictionaries are up to date");  
+       }
+       
        /*
         *      If the configuration parameters can't be parsed, then
         *      fail.
@@ -802,7 +854,10 @@ static rlm_rcode_t cache_it(void *instance, REQUEST *request)
        /*
         *      If yes, only return whether we found a valid cache entry
         */
-       vp = pairfind(request->config_items, PW_CACHE_STATUS_ONLY, 0, TAG_ANY);
+       vp = pairfind(request->config_items,
+                     inst->cache_status_only->attr, 
+                     inst->cache_status_only->vendor,
+                     TAG_ANY);
        if (vp && vp->vp_integer) {
                rcode = c ? RLM_MODULE_OK:
                            RLM_MODULE_NOTFOUND;