Module: sip-router
Branch: master
Commit: d997ecfc1df1781b7276b796c443f7d6f1f7cc2a
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d997ecf…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Mon Apr 18 23:20:44 2011 +0200
dispatcher(k): added RPC commands
- new RPC commands to replace the MI ones
---
modules_k/dispatcher/dispatch.c | 42 ++-----
modules_k/dispatcher/dispatch.h | 34 ++++++
modules_k/dispatcher/dispatcher.c | 218 +++++++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+), 31 deletions(-)
diff --git a/modules_k/dispatcher/dispatch.c b/modules_k/dispatcher/dispatch.c
index 93274f7..a056dcb 100644
--- a/modules_k/dispatcher/dispatch.c
+++ b/modules_k/dispatcher/dispatch.c
@@ -86,37 +86,6 @@ static int _ds_table_version = DS_TABLE_VERSION;
static ds_ht_t *_dsht_load = NULL;
-typedef struct _ds_attrs
-{
- str body;
- str duid;
- int maxload;
- int weight;
-} ds_attrs_t;
-
-typedef struct _ds_dest
-{
- str uri;
- int flags;
- int priority;
- int dload;
- ds_attrs_t attrs;
- struct ip_addr ip_address; /*!< IP-Address of the entry */
- unsigned short int port; /*!< Port of the request URI */
- int failure_count;
- struct _ds_dest *next;
-} ds_dest_t;
-
-typedef struct _ds_set
-{
- int id; /*!< id of dst set */
- int nr; /*!< number of items in dst set */
- int last; /*!< last used item in dst set (round robin) */
- int wlast; /*!< last used item in dst set (by weight) */
- ds_dest_t *dlist;
- unsigned int wlist[100];
- struct _ds_set *next;
-} ds_set_t;
extern int ds_force_dst;
@@ -2449,3 +2418,14 @@ int bind_dispatcher(dispatcher_api_t* api)
api->is_from = ds_is_from_list;
return 0;
}
+
+
+ds_set_t *ds_get_list(void)
+{
+ return _ds_list;
+}
+
+int ds_get_list_nr(void)
+{
+ return _ds_list_nr;
+}
diff --git a/modules_k/dispatcher/dispatch.h b/modules_k/dispatcher/dispatch.h
index f15cfbf..df95842 100644
--- a/modules_k/dispatcher/dispatch.h
+++ b/modules_k/dispatcher/dispatch.h
@@ -128,5 +128,39 @@ void ds_ht_timer(unsigned int ticks, void *param);
*/
int ds_ping_check_rplcode(int);
+typedef struct _ds_attrs
+{
+ str body;
+ str duid;
+ int maxload;
+ int weight;
+} ds_attrs_t;
+
+typedef struct _ds_dest
+{
+ str uri;
+ int flags;
+ int priority;
+ int dload;
+ ds_attrs_t attrs;
+ struct ip_addr ip_address; /*!< IP-Address of the entry */
+ unsigned short int port; /*!< Port of the request URI */
+ int failure_count;
+ struct _ds_dest *next;
+} ds_dest_t;
+
+typedef struct _ds_set
+{
+ int id; /*!< id of dst set */
+ int nr; /*!< number of items in dst set */
+ int last; /*!< last used item in dst set (round robin) */
+ int wlast; /*!< last used item in dst set (by weight) */
+ ds_dest_t *dlist;
+ unsigned int wlist[100];
+ struct _ds_set *next;
+} ds_set_t;
+
+ds_set_t *ds_get_list(void);
+int ds_get_list_nr(void);
#endif
diff --git a/modules_k/dispatcher/dispatcher.c b/modules_k/dispatcher/dispatcher.c
index 0b8b8c8..2fb8cb6 100644
--- a/modules_k/dispatcher/dispatcher.c
+++ b/modules_k/dispatcher/dispatcher.c
@@ -62,6 +62,8 @@
#include "../../route.h"
#include "../../mem/mem.h"
#include "../../mod_fix.h"
+#include "../../rpc.h"
+#include "../../rpc_lookup.h"
#include "ds_ht.h"
#include "dispatch.h"
@@ -138,6 +140,7 @@ static int mod_init(void);
static int child_init(int);
static int ds_parse_reply_codes();
+static int ds_init_rpc(void);
static int w_ds_select_dst(struct sip_msg*, char*, char*);
static int w_ds_select_domain(struct sip_msg*, char*, char*);
@@ -256,6 +259,11 @@ static int mod_init(void)
LM_ERR("failed to register MI commands\n");
return -1;
}
+ if(ds_init_rpc()<0)
+ {
+ LM_ERR("failed to register RPC commands\n");
+ return -1;
+ }
if (dst_avp_param.s)
dst_avp_param.len = strlen(dst_avp_param.s);
@@ -878,3 +886,213 @@ int ds_ping_check_rplcode(int code)
void ds_ping_reply_codes_update(str* gname, str* name){
ds_parse_reply_codes();
}
+
+/*** RPC implementation ***/
+
+static const char* dispatcher_rpc_reload_doc[2] = {
+ "Reload dispatcher destination sets",
+ 0
+};
+
+
+/*
+ * RPC command to reload dispatcher destination sets
+ */
+static void dispatcher_rpc_reload(rpc_t* rpc, void* ctx)
+{
+ if(dstid_avp_name.n!=0) {
+ LM_ERR("No reload support when call load dispatching is enabled."
+ " Do not set dstid_avp param if you do not use alg 10.\n");
+ rpc->fault(ctx, 500, "Command disabled");
+ return ;
+ }
+
+ if(!ds_db_url.s) {
+ if (ds_load_list(dslistfile)!=0) {
+ rpc->fault(ctx, 500, "Reload Failed");
+ return;
+ }
+ } else {
+ if(ds_load_db()<0) {
+ rpc->fault(ctx, 500, "Reload Failed");
+ return;
+ }
+ }
+ return;
+}
+
+
+
+static const char* dispatcher_rpc_list_doc[2] = {
+ "Return the content of dispatcher sets",
+ 0
+};
+
+
+/*
+ * RPC command to print dispatcher destination sets
+ */
+static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
+{
+ void* th;
+ void* ih;
+ void* vh;
+ int j;
+ char c[3];
+ str data = {"", 0};
+ ds_set_t *ds_list;
+ int ds_list_nr;
+ ds_set_t *list;
+
+ ds_list = ds_get_list();
+ ds_list_nr = ds_get_list_nr();
+
+ if(ds_list==NULL || ds_list_nr<=0)
+ {
+ LM_ERR("no destination sets\n");
+ rpc->fault(ctx, 500, "No Destination Sets");
+ return;
+ }
+
+ /* add entry node */
+ if (rpc->add(ctx, "{", &th) < 0)
+ {
+ rpc->fault(c, 500, "Internal error root reply");
+ return;
+ }
+ if(rpc->struct_add(th, "d{",
+ "SET_NO", ds_list_nr,
+ "SET", &ih)<0)
+ {
+ rpc->fault(c, 500, "Internal error set structure");
+ return;
+ }
+
+
+ for(list = ds_list; list!= NULL; list= list->next)
+ {
+ if(rpc->struct_add(ih, "d",
+ "SET_ID", list->id)<0)
+ {
+ rpc->fault(c, 500, "Internal error creating set id");
+ return;
+ }
+
+ for(j=0; j<list->nr; j++)
+ {
+ if(rpc->struct_add(ih, "{",
+ "DEST", &vh)<0)
+ {
+ rpc->fault(c, 500, "Internal error creating dest");
+ return;
+ }
+
+ memset(&c, 0, sizeof(c));
+ if (list->dlist[j].flags & DS_INACTIVE_DST)
+ c[0] = 'I';
+ else if (list->dlist[j].flags & DS_DISABLED_DST)
+ c[0] = 'D';
+ else
+ c[0] = 'A';
+
+ if (list->dlist[j].flags & DS_PROBING_DST)
+ c[1] = 'P';
+ else
+ c[1] = 'X';
+
+ if(rpc->struct_add(vh, "SsdS",
+ "URI", &list->dlist[j].uri,
+ "FLAGS", c,
+ "PRIORITY", list->dlist[j].priority,
+ "ATTRS", (list->dlist[j].attrs.body.s)?
+ &(list->dlist[j].attrs.body):&data)<0)
+ {
+ rpc->fault(c, 500, "Internal error creating dest struct");
+ return;
+ }
+ }
+ }
+
+ return;
+}
+
+
+static const char* dispatcher_rpc_set_state_doc[2] = {
+ "Set the state of a destination address",
+ 0
+};
+
+
+/*
+ * RPC command to set the state of a destination address
+ */
+static void dispatcher_rpc_set_state(rpc_t* rpc, void* ctx)
+{
+ int group;
+ str dest;
+ str state;
+ int stval;
+
+ if(rpc->scan(ctx, ".SdS", &state, &group, &dest)<3)
+ {
+ rpc->fault(ctx, 500, "Invalid Parameters");
+ return;
+ }
+ if(state.len<=0 || state.s==NULL)
+ {
+ LM_ERR("bad state value\n");
+ rpc->fault(ctx, 500, "Invalid State Parameter");
+ return;
+ }
+
+ stval = 0;
+ if(state.s[0]=='0' || state.s[0]=='I' || state.s[0]=='i') {
+ /* set inactive */
+ stval |= DS_INACTIVE_DST;
+ if((state.len>1) && (state.s[1]=='P' || state.s[1]=='p'))
+ stval |= DS_PROBING_DST;
+ } else if(state.s[0]=='1' || state.s[0]=='A' || state.s[0]=='a')
{
+ /* set active */
+ if((state.len>1) && (state.s[1]=='P' || state.s[1]=='p'))
+ stval |= DS_PROBING_DST;
+ } else if(state.s[0]=='2' || state.s[0]=='D' || state.s[0]=='d')
{
+ /* set disabled */
+ stval |= DS_DISABLED_DST;
+ } else {
+ LM_ERR("unknow state value\n");
+ rpc->fault(ctx, 500, "Unknown State Value");
+ return;
+ }
+
+ if(ds_reinit_state(group, &dest, stval)<0)
+ {
+ rpc->fault(ctx, 500, "State Update Failed");
+ return;
+ }
+
+ return;
+}
+
+
+rpc_export_t dispatcher_rpc_cmds[] = {
+ {"dispatcher.reload", dispatcher_rpc_reload,
+ dispatcher_rpc_reload_doc, 0},
+ {"dispatcher.list", dispatcher_rpc_list,
+ dispatcher_rpc_list_doc, 0},
+ {"dispatcher.set_state", dispatcher_rpc_set_state,
+ dispatcher_rpc_set_state_doc, 0},
+ {0, 0, 0, 0}
+};
+
+/**
+ * register RPC commands
+ */
+static int ds_init_rpc(void)
+{
+ if (rpc_register_array(dispatcher_rpc_cmds)!=0)
+ {
+ LM_ERR("failed to register RPC commands\n");
+ return -1;
+ }
+ return 0;
+}