Skip to content

Commit

Permalink
ratelimit: add rl_values() command
Browse files Browse the repository at this point in the history
Add a command to retrieve all the available pipes names
  • Loading branch information
razvancrainea committed Nov 20, 2024
1 parent 1687155 commit 632b46a
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 0 deletions.
36 changes: 36 additions & 0 deletions modules/ratelimit/doc/ratelimit_admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,42 @@ modparam("ratelimit", "slot_period", 100)
rl_reset_count("gw_$ru");
};
...
</programlisting>
</example>
</section>
<section id="func_rl_values" xreflabel="rl_values()">
<title>
<function moreinfo="none">rl_values(ret_avp, regexp)</function>
</title>
<para>
Returns all the available pipes' names in the <emphasis>ret_avp</emphasis>
output variable.
</para>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
<listitem><para>
<emphasis>ret_avp</emphasis> (string) - an AVP where the pipes'
names will be stored.
</para>
</listitem>
<listitem><para>
<emphasis>regexp</emphasis> (regex, optional) - a regular expression
used to filter the names of the pipes. If missing, all the pipes
are returned.
</para>
</listitem>
</itemizedlist>
<para>
This function can be used from any route.
</para>
<example>
<title><function>rl_values</function> usage</title>
<programlisting format="linespecific">
...
rl_values($avp(values));
for ($var(pipe) in $(avp(values)[*]))
xlog("RATELIMIT: $var(pipe): $rl_count($var(pipe))\n");
...
</programlisting>
</example>
</section>
Expand Down
16 changes: 16 additions & 0 deletions modules/ratelimit/ratelimit.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ static int pv_get_rl_count(struct sip_msg *msg, pv_param_t *param,
pv_value_t *res);
static int pv_parse_rl_count(pv_spec_p sp, const str *in);

static int fixup_avp(void** param);

static const cmd_export_t cmds[] = {
{"rl_check", (cmd_function)w_rl_check, {
{CMD_PARAM_STR,0,0},
Expand All @@ -137,6 +139,10 @@ static const cmd_export_t cmds[] = {
{CMD_PARAM_STR,0,0}, {0,0,0}},
REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|
BRANCH_ROUTE|ERROR_ROUTE|LOCAL_ROUTE|TIMER_ROUTE|EVENT_ROUTE},
{"rl_values", (cmd_function)w_rl_values, {
{CMD_PARAM_VAR,fixup_avp,0},
{CMD_PARAM_REGEX|CMD_PARAM_OPT,0, 0}, {0,0,0}},
ALL_ROUTES},
{0,0,{{0,0,0}},0}
};

Expand Down Expand Up @@ -1127,3 +1133,13 @@ static int pv_parse_rl_count(pv_spec_p sp, const str *in)
return 0;

}

static int fixup_avp(void** param)
{
if (((pv_spec_t*)*param)->type != PVT_AVP) {
LM_ERR("invalid pvar type - only AVPs are allowed!\n");
return E_SCRIPT;
}

return 0;
}
1 change: 1 addition & 0 deletions modules/ratelimit/ratelimit.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ int w_rl_check(struct sip_msg*, str *, int *, str *);
int w_rl_dec(struct sip_msg*, str *);
int w_rl_reset(struct sip_msg*, str *);
int w_rl_set_count(str, int);
int w_rl_values(struct sip_msg*, pv_spec_t *out, regex_t *regexp);
int rl_stats(mi_item_t *, str *, str *, int);
int rl_pipe_check(rl_pipe_t *);
int rl_get_counter_value(str *);
Expand Down
47 changes: 47 additions & 0 deletions modules/ratelimit/ratelimit_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,3 +1169,50 @@ int rl_get_counter_value(str *key)
RL_RELEASE_LOCK(hash_idx);
return ret;
}

int w_rl_values(struct sip_msg* msg, pv_spec_t *out, regex_t *regexp)
{
int i;
map_iterator_t it;
str *key, nkey;
regmatch_t pmatch;
pv_value_t val;

val.flags = PV_VAL_STR;

/* iterate through each map */
for (i = 0; i < rl_htable.size; i++) {
RL_GET_LOCK(i);
/* iterate through all the entries */
if (map_first(rl_htable.maps[i], &it) < 0) {
LM_ERR("map doesn't exist\n");
continue;
}
for (; iterator_is_valid(&it);) {
key = iterator_key(&it);
if (!key) {
LM_ERR("cannot retrieve pipe key\n");
goto next_it;
}
if (regexp) {
if (pkg_nt_str_dup(&nkey, key) != 0) {
LM_ERR("oom for duplicating %.*s\n", key->len, key->s);
goto next_it;
}
if (regexec(regexp, nkey.s, 1, &pmatch, 0) != 0) {
pkg_free(nkey.s);
goto next_it;
}
pkg_free(nkey.s);
}
val.rs = *key;
if (pv_set_value(msg, out, 0, &val) != 0)
LM_ERR("could not set key %.*s\n", key->len, key->s);
next_it:
if (iterator_next(&it) < 0)
break;
}
RL_RELEASE_LOCK(i);
}
return 1;
}

0 comments on commit 632b46a

Please sign in to comment.