Skip to content

Commit 632b46a

Browse files
committed
ratelimit: add rl_values() command
Add a command to retrieve all the available pipes names
1 parent 1687155 commit 632b46a

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

modules/ratelimit/doc/ratelimit_admin.xml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,42 @@ modparam("ratelimit", "slot_period", 100)
650650
rl_reset_count("gw_$ru");
651651
};
652652
...
653+
</programlisting>
654+
</example>
655+
</section>
656+
<section id="func_rl_values" xreflabel="rl_values()">
657+
<title>
658+
<function moreinfo="none">rl_values(ret_avp, regexp)</function>
659+
</title>
660+
<para>
661+
Returns all the available pipes' names in the <emphasis>ret_avp</emphasis>
662+
output variable.
663+
</para>
664+
<para>Meaning of the parameters is as follows:</para>
665+
<itemizedlist>
666+
<listitem><para>
667+
<emphasis>ret_avp</emphasis> (string) - an AVP where the pipes'
668+
names will be stored.
669+
</para>
670+
</listitem>
671+
<listitem><para>
672+
<emphasis>regexp</emphasis> (regex, optional) - a regular expression
673+
used to filter the names of the pipes. If missing, all the pipes
674+
are returned.
675+
</para>
676+
</listitem>
677+
</itemizedlist>
678+
<para>
679+
This function can be used from any route.
680+
</para>
681+
<example>
682+
<title><function>rl_values</function> usage</title>
683+
<programlisting format="linespecific">
684+
...
685+
rl_values($avp(values));
686+
for ($var(pipe) in $(avp(values)[*]))
687+
xlog("RATELIMIT: $var(pipe): $rl_count($var(pipe))\n");
688+
...
653689
</programlisting>
654690
</example>
655691
</section>

modules/ratelimit/ratelimit.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ static int pv_get_rl_count(struct sip_msg *msg, pv_param_t *param,
122122
pv_value_t *res);
123123
static int pv_parse_rl_count(pv_spec_p sp, const str *in);
124124

125+
static int fixup_avp(void** param);
126+
125127
static const cmd_export_t cmds[] = {
126128
{"rl_check", (cmd_function)w_rl_check, {
127129
{CMD_PARAM_STR,0,0},
@@ -137,6 +139,10 @@ static const cmd_export_t cmds[] = {
137139
{CMD_PARAM_STR,0,0}, {0,0,0}},
138140
REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|
139141
BRANCH_ROUTE|ERROR_ROUTE|LOCAL_ROUTE|TIMER_ROUTE|EVENT_ROUTE},
142+
{"rl_values", (cmd_function)w_rl_values, {
143+
{CMD_PARAM_VAR,fixup_avp,0},
144+
{CMD_PARAM_REGEX|CMD_PARAM_OPT,0, 0}, {0,0,0}},
145+
ALL_ROUTES},
140146
{0,0,{{0,0,0}},0}
141147
};
142148

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

11291135
}
1136+
1137+
static int fixup_avp(void** param)
1138+
{
1139+
if (((pv_spec_t*)*param)->type != PVT_AVP) {
1140+
LM_ERR("invalid pvar type - only AVPs are allowed!\n");
1141+
return E_SCRIPT;
1142+
}
1143+
1144+
return 0;
1145+
}

modules/ratelimit/ratelimit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ int w_rl_check(struct sip_msg*, str *, int *, str *);
140140
int w_rl_dec(struct sip_msg*, str *);
141141
int w_rl_reset(struct sip_msg*, str *);
142142
int w_rl_set_count(str, int);
143+
int w_rl_values(struct sip_msg*, pv_spec_t *out, regex_t *regexp);
143144
int rl_stats(mi_item_t *, str *, str *, int);
144145
int rl_pipe_check(rl_pipe_t *);
145146
int rl_get_counter_value(str *);

modules/ratelimit/ratelimit_helper.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,3 +1169,50 @@ int rl_get_counter_value(str *key)
11691169
RL_RELEASE_LOCK(hash_idx);
11701170
return ret;
11711171
}
1172+
1173+
int w_rl_values(struct sip_msg* msg, pv_spec_t *out, regex_t *regexp)
1174+
{
1175+
int i;
1176+
map_iterator_t it;
1177+
str *key, nkey;
1178+
regmatch_t pmatch;
1179+
pv_value_t val;
1180+
1181+
val.flags = PV_VAL_STR;
1182+
1183+
/* iterate through each map */
1184+
for (i = 0; i < rl_htable.size; i++) {
1185+
RL_GET_LOCK(i);
1186+
/* iterate through all the entries */
1187+
if (map_first(rl_htable.maps[i], &it) < 0) {
1188+
LM_ERR("map doesn't exist\n");
1189+
continue;
1190+
}
1191+
for (; iterator_is_valid(&it);) {
1192+
key = iterator_key(&it);
1193+
if (!key) {
1194+
LM_ERR("cannot retrieve pipe key\n");
1195+
goto next_it;
1196+
}
1197+
if (regexp) {
1198+
if (pkg_nt_str_dup(&nkey, key) != 0) {
1199+
LM_ERR("oom for duplicating %.*s\n", key->len, key->s);
1200+
goto next_it;
1201+
}
1202+
if (regexec(regexp, nkey.s, 1, &pmatch, 0) != 0) {
1203+
pkg_free(nkey.s);
1204+
goto next_it;
1205+
}
1206+
pkg_free(nkey.s);
1207+
}
1208+
val.rs = *key;
1209+
if (pv_set_value(msg, out, 0, &val) != 0)
1210+
LM_ERR("could not set key %.*s\n", key->len, key->s);
1211+
next_it:
1212+
if (iterator_next(&it) < 0)
1213+
break;
1214+
}
1215+
RL_RELEASE_LOCK(i);
1216+
}
1217+
return 1;
1218+
}

0 commit comments

Comments
 (0)