Browse Source

dispatcher: new rpc command dispatcher.set_duid_state

- set the state of a destination by matching on duid attribute
  kamctl rpc dispatcher.set_duid_state <state> <setid> <duid>
- example: kamctl rpc dispatcher.set_duid_state i 1 xyz
- GH #2085
Daniel-Constantin Mierla 5 years ago
parent
commit
b7b0f25871

+ 41 - 0
src/modules/dispatcher/dispatch.c

@@ -2978,6 +2978,47 @@ int ds_reinit_state(int group, str *address, int state)
 	return -1;
 }
 
+/**
+ *
+ */
+int ds_reinit_duid_state(int group, str *vduid, int state)
+{
+	int i = 0;
+	ds_set_t *idx = NULL;
+
+	if(_ds_list == NULL || _ds_list_nr <= 0) {
+		LM_ERR("the list is null\n");
+		return -1;
+	}
+
+	/* get the index of the set */
+	if(ds_get_index(group, *crt_idx, &idx) != 0) {
+		LM_ERR("destination set [%d] not found\n", group);
+		return -1;
+	}
+
+	for(i = 0; i < idx->nr; i++) {
+		if(idx->dlist[i].attrs.duid.len == vduid->len
+				&& strncasecmp(idx->dlist[i].attrs.duid.s, vduid->s, vduid->len)
+						   == 0) {
+			int old_state = idx->dlist[i].flags;
+			/* reset the bits used for states */
+			idx->dlist[i].flags &= ~(DS_STATES_ALL);
+			/* set the new states */
+			idx->dlist[i].flags |= state;
+			if(idx->dlist[i].attrs.rweight > 0) {
+				ds_reinit_rweight_on_state_change(
+						old_state, idx->dlist[i].flags, idx);
+			}
+
+			return 0;
+		}
+	}
+	LM_ERR("destination duid [%d : %.*s] not found\n", group, vduid->len,
+			vduid->s);
+	return -1;
+}
+
 /**
  *
  */

+ 1 - 0
src/modules/dispatcher/dispatch.h

@@ -146,6 +146,7 @@ int ds_update_state(sip_msg_t *msg, int group, str *address, int state,
 		ds_rctx_t *rctx);
 int ds_reinit_state(int group, str *address, int state);
 int ds_reinit_state_all(int group, int state);
+int ds_reinit_duid_state(int group, str *vduid, int state);
 int ds_mark_dst(struct sip_msg *msg, int mode);
 int ds_print_list(FILE *fout);
 int ds_log_sets(void);

+ 36 - 9
src/modules/dispatcher/dispatcher.c

@@ -1661,14 +1661,10 @@ static void dispatcher_rpc_list(rpc_t *rpc, void *ctx)
 }
 
 
-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
+ * RPC command to set the state of a destination address or duid
  */
-static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
+static void dispatcher_rpc_set_state_helper(rpc_t *rpc, void *ctx, int mattr)
 {
 	int group;
 	str dest;
@@ -1712,9 +1708,16 @@ static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
 	if(dest.len == 3 && strncmp(dest.s, "all", 3) == 0) {
 		ds_reinit_state_all(group, stval);
 	} else {
-		if(ds_reinit_state(group, &dest, stval) < 0) {
-			rpc->fault(ctx, 500, "State Update Failed");
-			return;
+		if (mattr==1) {
+			if(ds_reinit_duid_state(group, &dest, stval) < 0) {
+				rpc->fault(ctx, 500, "State Update Failed");
+				return;
+			}
+		} else {
+			if(ds_reinit_state(group, &dest, stval) < 0) {
+				rpc->fault(ctx, 500, "State Update Failed");
+				return;
+			}
 		}
 	}
 
@@ -1722,6 +1725,28 @@ static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
 }
 
 
+static const char *dispatcher_rpc_set_state_doc[2] = {
+		"Set the state of a destination by address", 0};
+
+/*
+ * RPC command to set the state of a destination address
+ */
+static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
+{
+	dispatcher_rpc_set_state_helper(rpc, ctx, 0);
+}
+
+static const char *dispatcher_rpc_set_duid_state_doc[2] = {
+		"Set the state of a destination by duid", 0};
+
+/*
+ * RPC command to set the state of a destination duid
+ */
+static void dispatcher_rpc_set_duid_state(rpc_t *rpc, void *ctx)
+{
+	dispatcher_rpc_set_state_helper(rpc, ctx, 1);
+}
+
 static const char *dispatcher_rpc_ping_active_doc[2] = {
 		"Manage setting on/off the pinging (keepalive) of destinations", 0};
 
@@ -1867,6 +1892,8 @@ rpc_export_t dispatcher_rpc_cmds[] = {
 		dispatcher_rpc_list_doc,   0},
 	{"dispatcher.set_state",   dispatcher_rpc_set_state,
 		dispatcher_rpc_set_state_doc,   0},
+	{"dispatcher.set_duid_state",   dispatcher_rpc_set_duid_state,
+		dispatcher_rpc_set_duid_state_doc,   0},
 	{"dispatcher.ping_active",   dispatcher_rpc_ping_active,
 		dispatcher_rpc_ping_active_doc, 0},
 	{"dispatcher.add",   dispatcher_rpc_add,