Skip to content

Commit

Permalink
Save pre-compile xlat's for "update", and use them at run time
Browse files Browse the repository at this point in the history
  • Loading branch information
alandekok committed Mar 21, 2014
1 parent 04a5829 commit 1c25269
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
6 changes: 5 additions & 1 deletion src/include/map.h
Expand Up @@ -78,11 +78,14 @@ typedef enum vpt_type {
VPT_TYPE_LIST, //!< Is a list.
VPT_TYPE_REGEX, //!< Is a regex.
VPT_TYPE_EXEC, //!< Needs to be executed.
VPT_TYPE_DATA //!< is a value_data_t
VPT_TYPE_DATA, //!< is a value_data_t
VPT_TYPE_XLAT_STRUCT, //!< pre-parsed xlat_exp_t in vpd.ptr
} vpt_type_t;

extern const FR_NAME_NUMBER vpt_types[];

typedef struct xlat_exp xlat_exp_t;

/** A pre-parsed template attribute
*
* Value pair template, used when processing various mappings sections
Expand All @@ -102,6 +105,7 @@ typedef struct value_pair_tmpl_t {

DICT_ATTR const *da; //!< Resolved dictionary attribute.
value_data_t const *vpd; //!< actual data
xlat_exp_t *xlat; //!< pre-parsed xlat_exp_t
size_t length; //!< of the vpd data
} value_pair_tmpl_t;

Expand Down
1 change: 0 additions & 1 deletion src/include/parser.h
Expand Up @@ -106,7 +106,6 @@ bool fr_condition_walk(fr_cond_t *head, bool (*callback)(void *, fr_cond_t *), v
/*
* In xlat.c for now
*/
typedef struct xlat_exp xlat_exp_t;
ssize_t xlat_tokenize(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
char const **error);
size_t xlat_sprint(char *buffer, size_t bufsize, xlat_exp_t const *node);
Expand Down
8 changes: 6 additions & 2 deletions src/main/modcall.c
Expand Up @@ -2652,7 +2652,6 @@ static bool modcall_pass2_update(modgroup *g)

fmt = talloc_strdup(map->src, map->src->name);
slen = xlat_tokenize(map->src, fmt, &head, &error);
talloc_free(fmt);

if (slen < 0) {
size_t offset;
Expand All @@ -2671,7 +2670,12 @@ static bool modcall_pass2_update(modgroup *g)
free(spbuf);
return false;
}
talloc_free(head);

/*
* Re-write it to be a pre-parsed XLAT structure.
*/
map->src->type = VPT_TYPE_XLAT_STRUCT;
map->src->xlat = head;
}

return true;
Expand Down
39 changes: 39 additions & 0 deletions src/main/valuepair.c
Expand Up @@ -1003,6 +1003,7 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
break;

case VPT_TYPE_XLAT:
case VPT_TYPE_XLAT_STRUCT:
vp_prints_value(buffer, sizeof(buffer), vp, '"');
value = buffer;
break;
Expand Down Expand Up @@ -1219,6 +1220,7 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma

switch (map->src->type) {
case VPT_TYPE_XLAT:
case VPT_TYPE_XLAT_STRUCT:
case VPT_TYPE_LITERAL:
case VPT_TYPE_DATA:
vp = pairalloc(request, da);
Expand All @@ -1234,6 +1236,42 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma
* And parse the RHS
*/
switch (map->src->type) {
case VPT_TYPE_XLAT_STRUCT:
rad_assert(map->dst->da); /* Need to know where were going to write the new attribute */
/*
* Don't call unnecessary expansions
*/
if (strchr(map->src->name, '%') != NULL) {
ssize_t slen;
char *str = NULL;

rad_assert(map->src->xlat != NULL);
slen = radius_axlat_struct(&str, request, map->src->xlat, NULL, NULL);
if (slen < 0) {
rcode = slen;
goto error;
}

/*
* We do the debug printing because radius_axlat_struct
* doesn't have access to the original string. It's been
* mangled during the parsing to xlat_exp_t
*/
RDEBUG2("EXPAND %s", map->src->name);
RDEBUG2(" --> %s", str);

rcode = pairparsevalue(vp, str);
talloc_free(str);
if (!rcode) {
pairfree(&vp);
rcode = -1;
goto error;
}

break;
}
goto parse_literal;

case VPT_TYPE_XLAT:
rad_assert(map->dst->da); /* Need to know where were going to write the new attribute */
/*
Expand Down Expand Up @@ -1261,6 +1299,7 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma
/* FALL-THROUGH */

case VPT_TYPE_LITERAL:
parse_literal:
if (!pairparsevalue(vp, map->src->name)) {
rcode = -2;
goto error;
Expand Down

0 comments on commit 1c25269

Please sign in to comment.