From: Arran Cudbard-Bell Date: Wed, 16 Jan 2013 19:44:17 +0000 (+0000) Subject: Dynamically resolve dictionary entrys for control attrs X-Git-Tag: release_3_0_0_beta1~1308 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aeffe365c0ea422e1838f758f7f0db9003c610ca;p=thirdparty%2Ffreeradius-server.git Dynamically resolve dictionary entrys for control attrs Add control:Cache-Merge, when set to no makes the cache 'wo' --- diff --git a/share/dictionary.freeradius.internal b/share/dictionary.freeradius.internal index 5f546628ec5..652ebeead64 100644 --- a/share/dictionary.freeradius.internal +++ b/share/dictionary.freeradius.internal @@ -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 diff --git a/src/include/radius.h b/src/include/radius.h index c7a48161e93..3660248f6bc 100644 --- a/src/include/radius.h +++ b/src/include/radius.h @@ -241,9 +241,6 @@ #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 diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index 471e31b589d..f02023eb79a 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -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;