Explorar el Código

Merge pull request #1877 from tverlaan/ds_rpc_remove_memory

dispatcher: remove destination from in-memory dispatcher set
Daniel-Constantin Mierla hace 6 años
padre
commit
666353f326

+ 62 - 7
src/modules/dispatcher/dispatch.c

@@ -176,7 +176,7 @@ int ds_hash_load_destroy(void)
 /**
 /**
  * Recursivly iterate over ds_set and execute callback
  * Recursivly iterate over ds_set and execute callback
  */
  */
-void ds_iter_set(ds_set_t *node, void (*ds_action_cb)(ds_set_t *node, int i))
+void ds_iter_set(ds_set_t *node, void (*ds_action_cb)(ds_set_t *node, int i, void *arg), void *ds_action_arg)
 {
 {
 	if(!node)
 	if(!node)
 		return;
 		return;
@@ -184,16 +184,16 @@ void ds_iter_set(ds_set_t *node, void (*ds_action_cb)(ds_set_t *node, int i))
 	int i;
 	int i;
 
 
 	for(i = 0; i < 2; ++i)
 	for(i = 0; i < 2; ++i)
-		ds_iter_set(node->next[i], ds_action_cb);
+		ds_iter_set(node->next[i], ds_action_cb, ds_action_arg);
 
 
 	for(i = 0; i < node->nr; i++) {
 	for(i = 0; i < node->nr; i++) {
-		ds_action_cb(node, i);
+		ds_action_cb(node, i, ds_action_arg);
 	}
 	}
 
 
 	return;
 	return;
 }
 }
 
 
-void ds_log_dst_cb(ds_set_t *node, int i)
+void ds_log_dst_cb(ds_set_t *node, int i, void *arg)
 {
 {
 	LM_DBG("dst>> %d %.*s %d %d (%.*s,%d,%d,%d)\n", node->id,
 	LM_DBG("dst>> %d %.*s %d %d (%.*s,%d,%d,%d)\n", node->id,
 		node->dlist[i].uri.len, node->dlist[i].uri.s,
 		node->dlist[i].uri.len, node->dlist[i].uri.s,
@@ -208,7 +208,7 @@ void ds_log_dst_cb(ds_set_t *node, int i)
  */
  */
 void ds_log_set(ds_set_t *node)
 void ds_log_set(ds_set_t *node)
 {
 {
-	ds_iter_set(node, &ds_log_dst_cb);
+	ds_iter_set(node, &ds_log_dst_cb, NULL);
 
 
 	return;
 	return;
 }
 }
@@ -2350,7 +2350,7 @@ int ds_update_dst(struct sip_msg *msg, int upos, int mode)
 }
 }
 
 
 /* callback for adding nodes based on index */
 /* callback for adding nodes based on index */
-void ds_add_dest_cb(ds_set_t *node, int i)
+void ds_add_dest_cb(ds_set_t *node, int i, void *arg)
 {
 {
 	int setn;
 	int setn;
 
 
@@ -2378,7 +2378,7 @@ int ds_add_dst(int group, str *address, int flags)
 	ds_avl_destroy(&ds_lists[*next_idx]);
 	ds_avl_destroy(&ds_lists[*next_idx]);
 
 
 	// add all existing destinations
 	// add all existing destinations
-	ds_iter_set(_ds_list, &ds_add_dest_cb);
+	ds_iter_set(_ds_list, &ds_add_dest_cb, NULL);
 
 
 	// add new destination
 	// add new destination
 	if(add_dest2list(group, *address, flags, priority, &attrs,
 	if(add_dest2list(group, *address, flags, priority, &attrs,
@@ -2406,6 +2406,61 @@ error:
 	return -1;
 	return -1;
 }
 }
 
 
+/* callback for removing nodes based on setid & address */
+void ds_filter_dest_cb(ds_set_t *node, int i, void *arg)
+{
+	struct ds_filter_dest_cb_arg *filter_arg = (typeof(filter_arg)) arg;
+
+	if(node->id == filter_arg->setid && node->dlist[i].uri.len == filter_arg->dest->uri.len &&
+		strncmp(node->dlist[i].uri.s, filter_arg->dest->uri.s, filter_arg->dest->uri.len) == 0)
+		return;
+
+	if(add_dest2list(node->id, node->dlist[i].uri, node->dlist[i].flags,
+			node->dlist[i].priority, &node->dlist[i].attrs.body, *next_idx,
+			filter_arg->setn) != 0) {
+		LM_WARN("failed to add destination in group %d - %.*s\n",
+				node->id, node->dlist[i].uri.len, node->dlist[i].uri.s);
+	}
+	return;
+}
+
+/* remove dispatcher entry from in-memory dispatcher list */
+int ds_remove_dst(int group, str *address)
+{
+	int setn;
+	struct ds_filter_dest_cb_arg filter_arg;
+	ds_dest_t *dp = NULL;
+
+	setn = 0;
+
+	dp = pack_dest(*address, 0, 0, NULL);
+	filter_arg.setid = group;
+	filter_arg.dest = dp;
+	filter_arg.setn = &setn;
+
+	*next_idx = (*crt_idx + 1) % 2;
+	ds_avl_destroy(&ds_lists[*next_idx]);
+
+	// add existing destinations except destination that matches group & address
+	ds_iter_set(_ds_list, &ds_filter_dest_cb, &filter_arg);
+
+	if(reindex_dests(ds_lists[*next_idx]) != 0) {
+		LM_ERR("error on reindex\n");
+		goto error;
+	}
+
+	_ds_list_nr = setn;
+	*crt_idx = *next_idx;
+	ds_ht_clear_slots(_dsht_load);
+	ds_log_sets();
+	return 0;
+
+error:
+	ds_avl_destroy(&ds_lists[*next_idx]);
+	*next_idx = *crt_idx;
+	return -1;
+}
+
 int ds_mark_dst(struct sip_msg *msg, int state)
 int ds_mark_dst(struct sip_msg *msg, int state)
 {
 {
 	sr_xavp_t *rxavp = NULL;
 	sr_xavp_t *rxavp = NULL;

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

@@ -130,6 +130,7 @@ int ds_select_dst_limit(sip_msg_t *msg, int set, int alg, uint32_t limit,
 int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode);
 int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode);
 int ds_update_dst(struct sip_msg *msg, int upos, int mode);
 int ds_update_dst(struct sip_msg *msg, int upos, int mode);
 int ds_add_dst(int group, str *address, int flags);
 int ds_add_dst(int group, str *address, int flags);
+int ds_remove_dst(int group, str *address);
 int ds_update_state(sip_msg_t *msg, int group, str *address, int state);
 int ds_update_state(sip_msg_t *msg, int group, str *address, int state);
 int ds_reinit_state(int group, str *address, int state);
 int ds_reinit_state(int group, str *address, int state);
 int ds_reinit_state_all(int group, int state);
 int ds_reinit_state_all(int group, int state);
@@ -228,6 +229,12 @@ typedef struct _ds_select_state {
 	sr_xavp_t *lxavp;
 	sr_xavp_t *lxavp;
 } ds_select_state_t;
 } ds_select_state_t;
 
 
+struct ds_filter_dest_cb_arg {
+	int setid;
+	ds_dest_t *dest;
+	int *setn;
+};
+
 /* clang-format on */
 /* clang-format on */
 
 
 #define AVL_LEFT 0
 #define AVL_LEFT 0

+ 27 - 0
src/modules/dispatcher/dispatcher.c

@@ -1668,6 +1668,31 @@ static void dispatcher_rpc_add(rpc_t *rpc, void *ctx)
 	return;
 	return;
 }
 }
 
 
+static const char *dispatcher_rpc_remove_doc[2] = {
+		"Remove a destination address from memory", 0};
+
+
+/*
+ * RPC command to remove a destination address from memory
+ */
+static void dispatcher_rpc_remove(rpc_t *rpc, void *ctx)
+{
+	int group;
+	str dest;
+
+	if(rpc->scan(ctx, "dS", &group, &dest) < 2) {
+		rpc->fault(ctx, 500, "Invalid Parameters");
+		return;
+	}
+
+	if(ds_remove_dst(group, &dest) != 0) {
+		rpc->fault(ctx, 500, "Removing dispatcher dst failed");
+		return;
+	}
+
+	return;
+}
+
 /* clang-format off */
 /* clang-format off */
 rpc_export_t dispatcher_rpc_cmds[] = {
 rpc_export_t dispatcher_rpc_cmds[] = {
 	{"dispatcher.reload", dispatcher_rpc_reload,
 	{"dispatcher.reload", dispatcher_rpc_reload,
@@ -1680,6 +1705,8 @@ rpc_export_t dispatcher_rpc_cmds[] = {
 		dispatcher_rpc_ping_active_doc, 0},
 		dispatcher_rpc_ping_active_doc, 0},
 	{"dispatcher.add",   dispatcher_rpc_add,
 	{"dispatcher.add",   dispatcher_rpc_add,
 		dispatcher_rpc_add_doc, 0},
 		dispatcher_rpc_add_doc, 0},
+	{"dispatcher.remove",   dispatcher_rpc_remove,
+		dispatcher_rpc_remove_doc, 0},
 	{0, 0, 0, 0}
 	{0, 0, 0, 0}
 };
 };
 /* clang-format on */
 /* clang-format on */

+ 33 - 0
src/modules/dispatcher/doc/dispatcher_admin.xml

@@ -1831,6 +1831,39 @@ DEST: {
 &sercmd; dispatcher.add 2 sip:127.0.0.1:5080
 &sercmd; dispatcher.add 2 sip:127.0.0.1:5080
 &sercmd; dispatcher.add 3 sip:127.0.0.1:5075 8
 &sercmd; dispatcher.add 3 sip:127.0.0.1:5075 8
 ...
 ...
+</programlisting>
+    </section>
+		<section id="dispatcher.r.remove">
+		<title>
+		<function moreinfo="none">dispatcher.remove</function>
+		</title>
+		<para>
+		Remove a destination address from the in-memory dispatcher list. Reloading
+		the dispatcher from file or database will re-add destinations that are
+		removed using this command.
+		</para>
+		<para>
+		This command will remove all entries that match the group and address.
+		</para>
+		<para>
+		Name: <emphasis>dispatcher.remove</emphasis>
+		</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem><para>_group_: destination group id</para></listitem>
+
+			<listitem><para>_address_: address of the destination in the _group_</para></listitem>
+
+		</itemizedlist>
+		<para>
+		Example:
+		</para>
+<programlisting  format="linespecific">
+...
+# prototype: &sercmd; dispatcher.remove _group_ _address_
+&sercmd; dispatcher.remove 2 sip:127.0.0.1:5080
+&sercmd; dispatcher.remove 3 sip:127.0.0.1:5075;transport=udp
+...
 </programlisting>
 </programlisting>
     </section>
     </section>