You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules/lcr/lcr_rpc.c

246 lines
6.2 KiB

/*
* Various lcr related functions :: RPC API
*
* Copyright (C) 2009-2010 Juha Heinanen
*
* This file is part of SIP Router, a free SIP server.
*
* SIP Router is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* For a license to use the SIP Router software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* SIP Router is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*!
* \file
* \brief SIP-router lcr :: rpc API interface
* \ingroup lcr
* Module: \ref lcr
*/
#include "lcr_rpc.h"
#include "lcr_mod.h"
#include "../../ip_addr.h"
static const char* reload_doc[2] = {
"Reload lcr tables from database.",
0
};
static void reload(rpc_t* rpc, void* c)
{
lock_get(reload_lock);
if (reload_tables() != 1)
rpc->fault(c, 500, "LCR Module Reload Failed");
lock_release(reload_lock);
}
static const char* dump_gws_doc[2] = {
"Dump the contents of lcr_gws table.",
0
};
static void dump_gws(rpc_t* rpc, void* c)
{
void* st;
unsigned int i, j;
enum sip_protos transport;
str gw_name, hostname, params;
str prefix, tag;
struct gw_info *gws;
char buf[INT2STR_MAX_LEN], *start;
int len;
for (j = 1; j <= lcr_count_param; j++) {
gws = gw_pt[j];
for (i = 1; i <= gws[0].ip_addr.u.addr32[0]; i++) {
if (rpc->add(c, "{", &st) < 0) return;
rpc->struct_add(st, "d", "lcr_id", j);
rpc->struct_add(st, "d", "gw_id", gws[i].gw_id);
rpc->struct_add(st, "d", "gw_index", i);
gw_name.s=gws[i].gw_name;
gw_name.len=gws[i].gw_name_len;
rpc->struct_add(st, "S", "gw_name", &gw_name);
if (gws[i].scheme == SIP_URI_T) {
rpc->struct_add(st, "s", "scheme", "sip");
} else {
rpc->struct_add(st, "s", "scheme", "sips");
}
switch (gws[i].ip_addr.af) {
case AF_INET:
rpc->struct_printf(st, "ip_addr", "%d.%d.%d.%d",
gws[i].ip_addr.u.addr[0],
gws[i].ip_addr.u.addr[1],
gws[i].ip_addr.u.addr[2],
gws[i].ip_addr.u.addr[3]);
break;
case AF_INET6:
rpc->struct_printf(st, "ip_addr", "%x:%x:%x:%x:%x:%x:%x:%x",
gws[i].ip_addr.u.addr16[0],
gws[i].ip_addr.u.addr16[1],
gws[i].ip_addr.u.addr16[2],
gws[i].ip_addr.u.addr16[3],
gws[i].ip_addr.u.addr16[4],
gws[i].ip_addr.u.addr16[5],
gws[i].ip_addr.u.addr16[6],
gws[i].ip_addr.u.addr16[7]);
break;
case 0:
rpc->struct_add(st, "s", "ip_addr", "0.0.0.0");
break;
}
hostname.s=gws[i].hostname;
hostname.len=gws[i].hostname_len;
rpc->struct_add(st, "S", "hostname", &hostname);
rpc->struct_add(st, "d", "port", gws[i].port);
params.s=gws[i].params;
params.len=gws[i].params_len;
rpc->struct_add(st, "S", "params", &params);
transport = gws[i].transport;
switch(transport){
case PROTO_UDP:
rpc->struct_add(st, "s", "transport", "UDP");
break;
case PROTO_TCP:
rpc->struct_add(st, "s", "transport", "TCP");
break;
case PROTO_TLS:
rpc->struct_add(st, "s", "transport", "TLS");
break;
case PROTO_SCTP:
rpc->struct_add(st, "s", "transport", "SCTP");
break;
case PROTO_OTHER:
rpc->struct_add(st, "s", "transport", "OTHER");
break;
case PROTO_NONE:
break;
}
prefix.s=gws[i].prefix;
prefix.len=gws[i].prefix_len;
tag.s=gws[i].tag;
tag.len=gws[i].tag_len;
start = int2strbuf(gws[i].defunct_until, &(buf[0]), INT2STR_MAX_LEN,
&len);
rpc->struct_add(st, "dSSds",
"strip", gws[i].strip,
"prefix", &prefix,
"tag", &tag,
"flags", gws[i].flags,
"defunct_until", start
);
}
}
}
static const char* dump_rules_doc[2] = {
"Dump the contents of the lcr_rules table.",
0
};
static void dump_rules(rpc_t* rpc, void* c)
{
int i, j;
struct rule_info **rules, *rule;
struct target *t;
void* st;
str prefix, from_uri, request_uri;
for (j = 1; j <= lcr_count_param; j++) {
rules = rule_pt[j];
for (i = 0; i < lcr_rule_hash_size_param; i++) {
rule = rules[i];
while (rule) {
if (rpc->add(c, "{", &st) < 0) return;
prefix.s=rule->prefix;
prefix.len=rule->prefix_len;
from_uri.s=rule->from_uri;
from_uri.len=rule->from_uri_len;
request_uri.s=rule->request_uri;
request_uri.len=rule->request_uri_len;
rpc->struct_add(st, "ddSSSd",
"lcr_id", j,
"rule_id", rule->rule_id,
"prefix", &prefix,
"from_uri", &from_uri,
"request_uri", &request_uri,
"stopper", rule->stopper
);
t = rule->targets;
while (t) {
if (rpc->add(c, "{", &st) < 0) return;
rpc->struct_add(st, "ddd",
"gw_index", t->gw_index,
"priority", t->priority,
"weight", t->weight
);
t = t->next;
}
rule=rule->next;
}
}
rule=rules[lcr_rule_hash_size_param];
while (rule) {
rpc->add(c, "d", rule->prefix_len);
rule=rule->next;
}
}
}
static const char* defunct_gw_doc[2] = {
"Defunct gateway until speficied time (Unix timestamp).",
0
};
static void defunct_gw(rpc_t* rpc, void* c)
{
unsigned int lcr_id, gw_id, until;
if (rpc->scan(c, "ddd", &lcr_id, &gw_id, &until) < 3) {
rpc->fault(c, 400, "lcr_id, gw_id, and timestamp parameters required");
return;
}
if (rpc_defunct_gw(lcr_id, gw_id, until) == 0) {
rpc->fault(c, 400, "parameter value error (see syslog)");
}
return;
}
rpc_export_t lcr_rpc[] = {
{"lcr.reload", reload, reload_doc, 0},
{"lcr.dump_gws", dump_gws, dump_gws_doc, 0},
{"lcr.dump_rules", dump_rules, dump_rules_doc, 0},
{"lcr.defunct_gw", defunct_gw, defunct_gw_doc, 0},
{0, 0, 0, 0}
};