Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modules:xmlrpc event_callback added for ksr routes #1736

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/modules/xmlrpc/doc/xmlrpc_admin.xml
Expand Up @@ -192,6 +192,45 @@ modparam("xmlrpc", "url_match", "^/RPC2")
</programlisting>
</example>
</section>
<section id="event_callback">
<title><varname>event_callback</varname> (string)</title>
<para>
The name of the function in the kemi configuration file (embedded
scripting language such as Lua, Python, ...) to be executed instead
of route blocks defined by route parameter for xmlrpc request.
</para>
<para>
This route will be called only for HTTP messages whose method is
either GET or POST. The message visible inside the route
will be a HTTP request converted to SIP (the uri will be fixed and
a fake via will be added).
</para>
<para>
The route should perform additional security checks to
ensure the client is authorized to execute management/RPC functions
and then it should call the <function>dispatch_rpc()</function>.
</para>
<example>
<title>Set <varname>event_callback</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("xmlrpc", "event_callback", "ksr_xmlrpc_event")
...
-- event callback function implemented in Lua
function ksr_xmlrpc_event(evname)
KSR.info("===== xmlrpc triggered event: " .. evname .. "\n");
local rpc_method = KSR.pv.get("$rm") or ""
if ((rpc_method == "POST" or rpc_method == "GET")) then
if (KSR.xmlrpc.dispatch_rpc() < 0) then
KSR.err("error while executing xmlrpc event")
end
end
return 1;
end
...
</programlisting>
</example>
</section>
</section>
<section>

Expand Down
56 changes: 42 additions & 14 deletions src/modules/xmlrpc/xmlrpc.c
Expand Up @@ -416,6 +416,7 @@ static regex_t xmlrpc_url_match_regexp;
static char* xmlrpc_url_skip = NULL;
static regex_t xmlrpc_url_skip_regexp;

static str xmlrpc_event_callback = STR_NULL;

/*
* Exported functions
Expand All @@ -438,6 +439,7 @@ static param_export_t params[] = {
{"mode", PARAM_INT, &xmlrpc_mode},
{"url_match", PARAM_STRING, &xmlrpc_url_match},
{"url_skip", PARAM_STRING, &xmlrpc_url_skip},
{"event_callback", PARAM_STR, &xmlrpc_event_callback},
{0, 0, 0}
};

Expand Down Expand Up @@ -2294,7 +2296,11 @@ static int em_receive_request(sip_msg_t* orig_msg,
{
int ret;
sip_msg_t tmp_msg, *msg;
int backup_rt;
struct run_act_ctx ra_ctx;
str evrtname = str_init("xmlrpc:request");
backup_rt = get_route_type();
sr_kemi_eng_t *keng = NULL;

ret=0;
if (new_buf && new_len) {
Expand Down Expand Up @@ -2328,17 +2334,30 @@ static int em_receive_request(sip_msg_t* orig_msg,
}
/* exec routing script */
init_run_actions_ctx(&ra_ctx);
if (run_actions(&ra_ctx, main_rt.rlist[xmlrpc_route_no], msg) < 0) {
ret=-1;
DBG("xmlrpc: error while trying script\n");
goto end;
if(xmlrpc_route_no>=0) {
if (run_actions(&ra_ctx, main_rt.rlist[xmlrpc_route_no], msg) < 0) {
ret=-1;
DBG("xmlrpc: error while trying script\n");
goto end;
}
}else{
keng = sr_kemi_eng_get();
if(keng!=NULL) {
if(keng->froute(msg, EVENT_ROUTE,
&xmlrpc_event_callback, &evrtname)<0) {
LM_ERR("error running event route kemi callback\n");
}
} else {
LM_ERR("no event route or kemi callback found for execution\n");
}
}
end:
exec_post_script_cb(msg, REQUEST_CB_TYPE); /* needed for example if tm is used */
/* reset_avps(); non needed, performed by the real receive_msg */
if (msg != orig_msg) { /* avoid double free (freed from receive_msg too) */
free_sip_msg(msg);
}
set_route_type(backup_rt);
return ret;
error:
return -1;
Expand Down Expand Up @@ -2583,22 +2602,31 @@ static int mod_init(void)
{
struct nonsip_hook nsh;
int route_no;
sr_kemi_eng_t *keng = NULL;

/* try to fix the xmlrpc route */
if (xmlrpc_route){
route_no=route_get(&main_rt, xmlrpc_route);
if (route_no==-1){
ERR("xmlrpc: failed to fix route \"%s\": route_get() failed\n",
xmlrpc_route);
if(xmlrpc_event_callback.s!=NULL && xmlrpc_event_callback.len>0) {
keng = sr_kemi_eng_get();
if(keng==NULL) {
LM_ERR("failed to find kemi engine\n");
return -1;
}
if (main_rt.rlist[route_no]==0){
WARN("xmlrpc: xmlrpc route \"%s\" is empty / doesn't exist\n",
xmlrpc_route);
xmlrpc_route_no=-1;
}else{
if (xmlrpc_route){
route_no=route_get(&main_rt, xmlrpc_route);
if (route_no==-1){
ERR("xmlrpc: failed to fix route \"%s\": route_get() failed\n",
xmlrpc_route);
return -1;
}
if (main_rt.rlist[route_no]==0){
WARN("xmlrpc: xmlrpc route \"%s\" is empty / doesn't exist\n",
xmlrpc_route);
}
xmlrpc_route_no=route_no;
}
xmlrpc_route_no=route_no;
}

/* bind the SL API */
if (sl_load_api(&slb)!=0) {
LM_ERR("cannot bind to SL API\n");
Expand Down