Browse code

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 authored on 22/05/2020 19:25:48
Showing 3 changed files
... ...
@@ -2981,6 +2981,47 @@ int ds_reinit_state(int group, str *address, int state)
2981 2981
 /**
2982 2982
  *
2983 2983
  */
2984
+int ds_reinit_duid_state(int group, str *vduid, int state)
2985
+{
2986
+	int i = 0;
2987
+	ds_set_t *idx = NULL;
2988
+
2989
+	if(_ds_list == NULL || _ds_list_nr <= 0) {
2990
+		LM_ERR("the list is null\n");
2991
+		return -1;
2992
+	}
2993
+
2994
+	/* get the index of the set */
2995
+	if(ds_get_index(group, *crt_idx, &idx) != 0) {
2996
+		LM_ERR("destination set [%d] not found\n", group);
2997
+		return -1;
2998
+	}
2999
+
3000
+	for(i = 0; i < idx->nr; i++) {
3001
+		if(idx->dlist[i].attrs.duid.len == vduid->len
3002
+				&& strncasecmp(idx->dlist[i].attrs.duid.s, vduid->s, vduid->len)
3003
+						   == 0) {
3004
+			int old_state = idx->dlist[i].flags;
3005
+			/* reset the bits used for states */
3006
+			idx->dlist[i].flags &= ~(DS_STATES_ALL);
3007
+			/* set the new states */
3008
+			idx->dlist[i].flags |= state;
3009
+			if(idx->dlist[i].attrs.rweight > 0) {
3010
+				ds_reinit_rweight_on_state_change(
3011
+						old_state, idx->dlist[i].flags, idx);
3012
+			}
3013
+
3014
+			return 0;
3015
+		}
3016
+	}
3017
+	LM_ERR("destination duid [%d : %.*s] not found\n", group, vduid->len,
3018
+			vduid->s);
3019
+	return -1;
3020
+}
3021
+
3022
+/**
3023
+ *
3024
+ */
2984 3025
 int ds_reinit_state_all(int group, int state)
2985 3026
 {
2986 3027
 	int i = 0;
... ...
@@ -146,6 +146,7 @@ int ds_update_state(sip_msg_t *msg, int group, str *address, int state,
146 146
 		ds_rctx_t *rctx);
147 147
 int ds_reinit_state(int group, str *address, int state);
148 148
 int ds_reinit_state_all(int group, int state);
149
+int ds_reinit_duid_state(int group, str *vduid, int state);
149 150
 int ds_mark_dst(struct sip_msg *msg, int mode);
150 151
 int ds_print_list(FILE *fout);
151 152
 int ds_log_sets(void);
... ...
@@ -1661,14 +1661,10 @@ static void dispatcher_rpc_list(rpc_t *rpc, void *ctx)
1661 1661
 }
1662 1662
 
1663 1663
 
1664
-static const char *dispatcher_rpc_set_state_doc[2] = {
1665
-		"Set the state of a destination address", 0};
1666
-
1667
-
1668 1664
 /*
1669
- * RPC command to set the state of a destination address
1665
+ * RPC command to set the state of a destination address or duid
1670 1666
  */
1671
-static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
1667
+static void dispatcher_rpc_set_state_helper(rpc_t *rpc, void *ctx, int mattr)
1672 1668
 {
1673 1669
 	int group;
1674 1670
 	str dest;
... ...
@@ -1712,9 +1708,16 @@ static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
1712 1712
 	if(dest.len == 3 && strncmp(dest.s, "all", 3) == 0) {
1713 1713
 		ds_reinit_state_all(group, stval);
1714 1714
 	} else {
1715
-		if(ds_reinit_state(group, &dest, stval) < 0) {
1716
-			rpc->fault(ctx, 500, "State Update Failed");
1717
-			return;
1715
+		if (mattr==1) {
1716
+			if(ds_reinit_duid_state(group, &dest, stval) < 0) {
1717
+				rpc->fault(ctx, 500, "State Update Failed");
1718
+				return;
1719
+			}
1720
+		} else {
1721
+			if(ds_reinit_state(group, &dest, stval) < 0) {
1722
+				rpc->fault(ctx, 500, "State Update Failed");
1723
+				return;
1724
+			}
1718 1725
 		}
1719 1726
 	}
1720 1727
 
... ...
@@ -1722,6 +1725,28 @@ static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
1722 1722
 }
1723 1723
 
1724 1724
 
1725
+static const char *dispatcher_rpc_set_state_doc[2] = {
1726
+		"Set the state of a destination by address", 0};
1727
+
1728
+/*
1729
+ * RPC command to set the state of a destination address
1730
+ */
1731
+static void dispatcher_rpc_set_state(rpc_t *rpc, void *ctx)
1732
+{
1733
+	dispatcher_rpc_set_state_helper(rpc, ctx, 0);
1734
+}
1735
+
1736
+static const char *dispatcher_rpc_set_duid_state_doc[2] = {
1737
+		"Set the state of a destination by duid", 0};
1738
+
1739
+/*
1740
+ * RPC command to set the state of a destination duid
1741
+ */
1742
+static void dispatcher_rpc_set_duid_state(rpc_t *rpc, void *ctx)
1743
+{
1744
+	dispatcher_rpc_set_state_helper(rpc, ctx, 1);
1745
+}
1746
+
1725 1747
 static const char *dispatcher_rpc_ping_active_doc[2] = {
1726 1748
 		"Manage setting on/off the pinging (keepalive) of destinations", 0};
1727 1749
 
... ...
@@ -1867,6 +1892,8 @@ rpc_export_t dispatcher_rpc_cmds[] = {
1867 1867
 		dispatcher_rpc_list_doc,   0},
1868 1868
 	{"dispatcher.set_state",   dispatcher_rpc_set_state,
1869 1869
 		dispatcher_rpc_set_state_doc,   0},
1870
+	{"dispatcher.set_duid_state",   dispatcher_rpc_set_duid_state,
1871
+		dispatcher_rpc_set_duid_state_doc,   0},
1870 1872
 	{"dispatcher.ping_active",   dispatcher_rpc_ping_active,
1871 1873
 		dispatcher_rpc_ping_active_doc, 0},
1872 1874
 	{"dispatcher.add",   dispatcher_rpc_add,