Add support for caching session-state
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 14 Apr 2015 04:05:23 +0000 (00:05 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 14 Apr 2015 17:16:22 +0000 (13:16 -0400)
So when we do session resumption, the session-state can be pulled from the session-cache

raddb/mods-available/cache
src/modules/rlm_cache/rlm_cache.c
src/modules/rlm_cache/rlm_cache.h
src/modules/rlm_cache/serialize.c

index 7ac69ff..7a7db68 100644 (file)
@@ -91,8 +91,12 @@ cache {
        #  represents the cache entry. see man unlang for more information
        #  on update blocks.
        #
+       #  Note: Only request, reply, control and session-state lists
+       #  are available in cache entries. Attempting to store attributes
+       #  in other lists will raise an error during config validation.
+       #
        update {
-               # [outer.]<list>:<attribute> <op> <value>
+               # <list>:<attribute> <op> <value>
 
                # Cache all instances of Reply-Message in the reply list
                reply:Reply-Message += &reply:Reply-Message
index 1d28463..8e733c8 100644 (file)
@@ -127,11 +127,6 @@ static void CC_HINT(nonnull) cache_merge(rlm_cache_t *inst, REQUEST *request, rl
 
        RDEBUG2("Merging cache entry into request");
 
-       if (c->control) {
-               rdebug_pair_list(L_DBG_LVL_2, request, c->control, "&control:");
-               radius_pairmove(request, &request->config, paircopy(request, c->control), false);
-       }
-
        if (c->packet && request->packet) {
                rdebug_pair_list(L_DBG_LVL_2, request, c->packet, "&request:");
                radius_pairmove(request, &request->packet->vps, paircopy(request->packet, c->packet), false);
@@ -142,6 +137,16 @@ static void CC_HINT(nonnull) cache_merge(rlm_cache_t *inst, REQUEST *request, rl
                radius_pairmove(request, &request->reply->vps, paircopy(request->reply, c->reply), false);
        }
 
+       if (c->control) {
+               rdebug_pair_list(L_DBG_LVL_2, request, c->control, "&control:");
+               radius_pairmove(request, &request->config, paircopy(request, c->control), false);
+       }
+
+       if (c->state) {
+               rdebug_pair_list(L_DBG_LVL_2, request, c->state, "&session-state:");
+               radius_pairmove(request, &request->state, paircopy(request->state, c->state), false);
+       }
+
        if (inst->stats) {
                rad_assert(request->packet != NULL);
                vp = pairfind(request->packet->vps, PW_CACHE_ENTRY_HITS, 0, TAG_ANY);
@@ -239,7 +244,7 @@ static rlm_rcode_t cache_insert(rlm_cache_t *inst, REQUEST *request, rlm_cache_h
                                char const *key, int ttl)
 {
        VALUE_PAIR *vp, *to_cache;
-       vp_cursor_t src_list, cached_request, cached_reply, cached_control;
+       vp_cursor_t src_list, packet, reply, control, state;
 
        value_pair_map_t const *map;
 
@@ -261,9 +266,10 @@ static rlm_rcode_t cache_insert(rlm_cache_t *inst, REQUEST *request, rlm_cache_h
 
        RDEBUG("Creating new cache entry");
 
-       fr_cursor_init(&cached_request, &c->packet);
-       fr_cursor_init(&cached_reply, &c->reply);
-       fr_cursor_init(&cached_control, &c->control);
+       fr_cursor_init(&packet, &c->packet);
+       fr_cursor_init(&reply, &c->reply);
+       fr_cursor_init(&control, &c->control);
+       fr_cursor_init(&state, &c->state);
 
        for (map = inst->maps; map != NULL; map = map->next) {
                rad_assert(map->lhs && map->rhs);
@@ -307,15 +313,19 @@ static rlm_rcode_t cache_insert(rlm_cache_t *inst, REQUEST *request, rlm_cache_h
 
                        switch (map->lhs->tmpl_list) {
                        case PAIR_LIST_REQUEST:
-                               fr_cursor_insert(&cached_request, vp);
+                               fr_cursor_insert(&packet, vp);
                                break;
 
                        case PAIR_LIST_REPLY:
-                               fr_cursor_insert(&cached_reply, vp);
+                               fr_cursor_insert(&reply, vp);
                                break;
 
                        case PAIR_LIST_CONTROL:
-                               fr_cursor_insert(&cached_control, vp);
+                               fr_cursor_insert(&control, vp);
+                               break;
+
+                       case PAIR_LIST_STATE:
+                               fr_cursor_insert(&state, vp);
                                break;
 
                        default:
@@ -589,6 +599,10 @@ static ssize_t cache_xlat(void *instance, REQUEST *request,
                vps = c->control;
                break;
 
+       case PAIR_LIST_STATE:
+               vps = c->state;
+               break;
+
        default:
                REDEBUG("Unsupported list \"%s\"", fr_int2str(pair_lists, list, "<UNKNOWN>"));
                ret = -1;
index acf8495..48e3ee3 100644 (file)
@@ -74,6 +74,7 @@ typedef struct rlm_cache_entry_t {
        VALUE_PAIR              *control;               //!< Cached control list.
        VALUE_PAIR              *packet;                //!< Cached request list.
        VALUE_PAIR              *reply;                 //!< Cached reply list.
+       VALUE_PAIR              *state;                 //!< Cached session-state list.
 } rlm_cache_entry_t;
 
 typedef int                    (*mod_instantiate_t)(CONF_SECTION *conf, rlm_cache_t *inst);
index c941b42..6d1a000 100644 (file)
@@ -104,6 +104,18 @@ int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t *c)
                }
        }
 
+       if (c->state) {
+               for (vp = fr_cursor_init(&cursor, &c->state);
+                    vp;
+                    vp = fr_cursor_next(&cursor)) {
+                       pair = vp_aprints(pairs, vp, '\'');
+                       if (!pair) goto error;
+
+                       to_store = talloc_asprintf_append_buffer(to_store, "&session-state:%s\n", pair);
+                       if (!to_store) goto error;
+               }
+       }
+
 finish:
        talloc_free(pairs);
        *out = to_store;
@@ -121,7 +133,7 @@ finish:
  */
 int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
 {
-       vp_cursor_t packet, control, reply;
+       vp_cursor_t packet, control, reply, state;
 
        TALLOC_CTX *store = NULL;
        char *p, *q;
@@ -134,6 +146,7 @@ int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
        fr_cursor_init(&packet, &c->packet);
        fr_cursor_init(&control, &c->control);
        fr_cursor_init(&reply, &c->reply);
+       fr_cursor_init(&state, &c->state);
 
        p = in;
 
@@ -210,6 +223,10 @@ int cache_deserialize(rlm_cache_entry_t *c, char *in, ssize_t inlen)
                        fr_cursor_insert(&reply, vp);
                        break;
 
+               case PAIR_LIST_STATE:
+                       fr_cursor_insert(&state, vp);
+                       break;
+
                default:
                        fr_strerror_printf("Invalid cache list for pair: %s", p);
                error: