Browse code

dialog: adding RPC dlg.kill_active_dlg command

- only handles active dialogs in state 4
- wipes out a given dialog callously
- no subcalls to dialog-ending functions
- dialog is then removed by the recurring cleaning function execution
- as discussed in sr-users in topic "[Dialog] Removing entries from dialog memory"

Julien Klingenmeyer authored on 25/10/2019 09:16:20 • Daniel-Constantin Mierla committed on 30/10/2019 10:42:55
Showing 3 changed files
... ...
@@ -2368,6 +2368,9 @@ static const char *rpc_end_dlg_entry_id_doc[2] = {
2368 2368
 static const char *rpc_dlg_terminate_dlg_doc[2] = {
2369 2369
         "End a given dialog based on callid", 0
2370 2370
 };
2371
+static const char *rpc_dlg_kill_active_dlg_doc[2] = {
2372
+        "Kill a given active dialog based on callid and tags", 0
2373
+};
2371 2374
 static const char *rpc_profile_get_size_doc[2] = {
2372 2375
 	"Returns the number of dialogs belonging to a profile", 0
2373 2376
 };
... ...
@@ -2435,6 +2438,58 @@ static void rpc_dlg_terminate_dlg(rpc_t *rpc,void *c){
2435 2438
     }
2436 2439
 }
2437 2440
 
2441
+static void rpc_dlg_kill_active_dlg(rpc_t *rpc,void *c){
2442
+	str callid = {NULL,0};
2443
+	str ftag = {NULL,0};
2444
+	str ttag = {NULL,0};
2445
+
2446
+	dlg_cell_t * dlg = NULL;
2447
+	unsigned int dir;
2448
+	int unref=1;
2449
+	dir = 0;
2450
+
2451
+	if(rpc->scan(c, ".S.S.S", &callid,&ftag,&ttag)<3) {
2452
+		LM_ERR("Unable to read the parameters dlg_terminate_dlg \n" );
2453
+		rpc->fault(c, 400, "Need a Callid ,from tag ,to tag");
2454
+		return;
2455
+	}
2456
+
2457
+	dlg=get_dlg(&callid, &ftag, &ttag, &dir);
2458
+
2459
+	if(dlg==NULL) {
2460
+		LM_ERR("Couldnt find callid in dialog '%.*s' \n",callid.len, callid.s);
2461
+		rpc->fault(c, 500, "Couldnt find callid in dialog");
2462
+		return;
2463
+	}
2464
+
2465
+	LM_DBG("Dialog is found with callid '%.*s' for kill_active_dlg rpc \n",
2466
+			callid.len, callid.s);
2467
+
2468
+	if(dlg->state != 4) {
2469
+		LM_ERR("Not handling dialog with callid '%.*s': should be in active state to run this command \n",
2470
+			callid.len, callid.s);
2471
+		rpc->fault(c, 500, "Dialog not in active state");
2472
+		return;
2473
+	}
2474
+
2475
+	/* Forcing next state for this dialog */
2476
+	dlg->state = 5;
2477
+	/* Updating timestamps, flags, dialog stats */
2478
+	dlg->init_ts = (unsigned int)(time(0));
2479
+	dlg->end_ts = (unsigned int)(time(0));
2480
+	dlg->dflags |= DLG_FLAG_NEW;
2481
+
2482
+	dlg_unref(dlg, unref);
2483
+	if_update_stat(dlg_enable_stats, active_dlgs, -1);
2484
+
2485
+	/* dlg_clean_run called by timer execution will handle timers deletion and all that stuff */
2486
+	LM_NOTICE("Dialog '%.*s' forced to deleted state: will be wiped out from memory in a few minutes \n",
2487
+			callid.len, callid.s);
2488
+
2489
+	rpc->add(c, "s", "Done");
2490
+
2491
+}
2492
+
2438 2493
 static void rpc_dlg_is_alive(rpc_t *rpc, void *c)
2439 2494
 {
2440 2495
 	str callid = {NULL, 0};
... ...
@@ -2780,6 +2835,7 @@ static rpc_export_t rpc_methods[] = {
2780 2835
 	{"dlg.profile_list", rpc_profile_print_dlgs, rpc_profile_print_dlgs_doc, RET_ARRAY},
2781 2836
 	{"dlg.bridge_dlg", rpc_dlg_bridge, rpc_dlg_bridge_doc, 0},
2782 2837
 	{"dlg.terminate_dlg", rpc_dlg_terminate_dlg, rpc_dlg_terminate_dlg_doc, 0},
2838
+	{"dlg.kill_active_dlg", rpc_dlg_kill_active_dlg, rpc_dlg_kill_active_dlg_doc, 0},
2783 2839
 	{"dlg.stats_active", rpc_dlg_stats_active, rpc_dlg_stats_active_doc, 0},
2784 2840
 	{"dlg.is_alive",  rpc_dlg_is_alive, rpc_dlg_is_alive_doc, 0},
2785 2841
 	{0, 0, 0, 0}
... ...
@@ -58,6 +58,11 @@
58 58
 			<surname>Tiwari</surname>
59 59
 			<email>surendratiwari3@gmail.com</email>
60 60
 		</editor>
61
+		<editor>
62
+			<firstname>Julien</firstname>
63
+			<surname>Klingenmeyer</surname>
64
+			<email>julien.klingenmeyer@corp.ovh.com</email>
65
+		</editor>
61 66
 	</authorgroup>
62 67
 	<copyright>
63 68
 		<year>2006</year>
... ...
@@ -2596,6 +2596,39 @@ if(has_totag()) {
2596 2596
 		<programlisting  format="linespecific">
2597 2597
 ...
2598 2598
 &kamcmd; dlg.end_dlg 342 56
2599
+...
2600
+		</programlisting>
2601
+		</section>
2602
+		<section>
2603
+			<title>dlg.kill_active_dlg</title>
2604
+			<para>
2605
+			Kills a given active dialog matching the dialog on Call-ID, From-Tag and To-Tag.
2606
+			</para>
2607
+		<para>Name: <emphasis>dlg.kill_active_dlg</emphasis></para>
2608
+		<para>Parameters:</para>
2609
+		<itemizedlist>
2610
+			<listitem><para>
2611
+				<emphasis>callid</emphasis> - Call-ID of active dialog to kill
2612
+			</para></listitem>
2613
+			<listitem><para>
2614
+				<emphasis>from_tag</emphasis> - From-Tag of active dialog to kill
2615
+			</para></listitem>
2616
+			<listitem><para>
2617
+				<emphasis>to_tag</emphasis> - To-tag of active dialog to kill
2618
+			</para></listitem>
2619
+		</itemizedlist>
2620
+		<para>
2621
+		This command only handles active dialogs (state 4), error is returned otherwise.
2622
+		Please be careful with it, it callously wipes out the given dialog: dialog ending
2623
+		functions will not be called, such as accounting end-of-call events, dialog-end
2624
+		events, module-generated BYE requests, etc. After executing the	command, dialog
2625
+		remains in memory until execution of the recurring function in charge of removing
2626
+		old dialogs (a "dialog in delete state is too old" will then be logged).
2627
+		</para>
2628
+		<para>RPC Command Format:</para>
2629
+		<programlisting  format="linespecific">
2630
+...
2631
+&kamcmd; dlg.kill_active_dlg callid12345 fromtag123 totag123
2599 2632
 ...
2600 2633
 		</programlisting>
2601 2634
 		</section>