Revision
15891
Author
anthm
Date
2009-12-10 18:28:54 -0600 (Thu, 10 Dec 2009)

Log Message

stop race condition in sofia where we tried to send an ack on a dead call and turn off early hangup by default (if you dont know that that is, good, do not document this)

Modified Paths

Diff

Modified: freeswitch/trunk/src/include/switch_core.h (15890 => 15891)


--- freeswitch/trunk/src/include/switch_core.h	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/include/switch_core.h	2009-12-11 00:28:54 UTC (rev 15891)
@@ -615,7 +615,7 @@
 
 SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session);
-SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force);
 
 /*! 
   \brief Provide the total number of sessions

Modified: freeswitch/trunk/src/include/switch_types.h (15890 => 15891)


--- freeswitch/trunk/src/include/switch_types.h	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/include/switch_types.h	2009-12-11 00:28:54 UTC (rev 15891)
@@ -241,7 +241,8 @@
 	SCF_VG = (1 << 3),
 	SCF_RESTART = (1 << 4),
 	SCF_SHUTDOWN_REQUESTED = (1 << 5),
-	SCF_USE_AUTO_NAT = (1 << 6)
+	SCF_USE_AUTO_NAT = (1 << 6),
+	SCF_EARLY_HANGUP = (1 << 7)
 } switch_core_flag_enum_t;
 typedef uint32_t switch_core_flag_t;
 
@@ -946,6 +947,7 @@
 	CF_BYPASS_MEDIA_AFTER_BRIDGE,
 	CF_LEG_HOLDING,
 	CF_BROADCAST_DROP_MEDIA,
+	CF_EARLY_HANGUP,
 	/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
 	CF_FLAG_MAX
 } switch_channel_flag_t;

Modified: freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c (15890 => 15891)


--- freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/mod/applications/mod_dptools/mod_dptools.c	2009-12-11 00:28:54 UTC (rev 15891)
@@ -2787,6 +2787,11 @@
 	switch_channel_set_flag(switch_core_session_get_channel(session), CF_VERBOSE_EVENTS);
 }
 
+SWITCH_STANDARD_APP(early_hangup_function)
+{
+	switch_channel_set_flag(switch_core_session_get_channel(session), CF_EARLY_HANGUP);
+}
+
 #define WAIT_FOR_SILENCE_SYNTAX "<silence_thresh> <silence_hits> <listen_hits> <timeout_ms> [<file>]"
 SWITCH_STANDARD_APP(wait_for_silence_function)
 {
@@ -2939,6 +2944,7 @@
 	SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function,
 				   "<ip> <acl | cidr> [<hangup_cause>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
 	SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
+	SWITCH_ADD_APP(app_interface, "early_hangup", "Enable early hangup", "", early_hangup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
 	SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
 	SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
 	SWITCH_ADD_APP(app_interface, "strftime", "strftime", "strftime", strftime_function, "[<epoch>|]<format string>", SAF_SUPPORT_NOMEDIA);

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (15890 => 15891)


--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	2009-12-11 00:28:54 UTC (rev 15891)
@@ -3833,6 +3833,7 @@
 	case nua_callstate_completed:
 	case nua_callstate_received:
 	case nua_callstate_proceeding:
+	case nua_callstate_completing:
 		if (!(session && channel && tech_pvt)) goto done;
 		break;
 	default:
@@ -3890,9 +3891,9 @@
 		break;
 	case nua_callstate_completing:
 		nua_ack(nh,
-				TAG_IF(tech_pvt && !zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+				TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
 				TAG_END());
-		break;
+		goto done;
 	case nua_callstate_received:
 		if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) {
 			if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {

Modified: freeswitch/trunk/src/switch_channel.c (15890 => 15891)


--- freeswitch/trunk/src/switch_channel.c	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/switch_channel.c	2009-12-11 00:28:54 UTC (rev 15891)
@@ -1911,7 +1911,7 @@
 
 		switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL);
 		switch_core_session_signal_state_change(channel->session);
-		switch_core_session_hangup_state(channel->session);
+		switch_core_session_hangup_state(channel->session, SWITCH_FALSE);
 	}
 
 	return channel->state;

Modified: freeswitch/trunk/src/switch_core.c (15890 => 15891)


--- freeswitch/trunk/src/switch_core.c	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/switch_core.c	2009-12-11 00:28:54 UTC (rev 15891)
@@ -1382,6 +1382,8 @@
 					if (tmp > -1 && tmp < 11) {
 						switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
 					}
+				} else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
+					switch_set_flag((&runtime), SCF_EARLY_HANGUP);
 				} else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
 					runtime.colorize_console = SWITCH_TRUE;
 				} else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {

Modified: freeswitch/trunk/src/switch_core_state_machine.c (15890 => 15891)


--- freeswitch/trunk/src/switch_core_state_machine.c	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/switch_core_state_machine.c	2009-12-11 00:28:54 UTC (rev 15891)
@@ -329,7 +329,7 @@
 				goto done;
 			case CS_HANGUP:	/* Deactivate and end the thread */
 				{
-					switch_core_session_hangup_state(session);				
+					switch_core_session_hangup_state(session, SWITCH_TRUE);				
 					switch_channel_set_state(session->channel, CS_REPORTING);
 				}
 
@@ -437,7 +437,7 @@
 }
 
 
-SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session)
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force)
 {
 	const char *hook_var;
 	switch_core_session_t *use_session = NULL;
@@ -454,15 +454,21 @@
 	const switch_state_handler_table_t *driver_state_handler = NULL;
 	const switch_state_handler_table_t *application_state_handler = NULL;
 
+	
+	if (!force) {
+		if (!switch_channel_test_flag(session->channel, CF_EARLY_HANGUP) && !switch_test_flag((&runtime), SCF_EARLY_HANGUP)) {
+			return;
+		}
 
-	if (switch_thread_self() != session->thread_id) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s thread mismatch skipping state handler.\n", 
-						  switch_channel_get_name(session->channel));
-		return;
+		if (switch_thread_self() != session->thread_id) {
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s thread mismatch skipping state handler.\n", 
+							  switch_channel_get_name(session->channel));
+			return;
+		}
 	}
 
 	if (switch_test_flag(session, SSF_HANGUP)) {
-		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s handler already called, skipping state handler.\n",
+		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s handler already called, skipping state handler.\n",
 						  switch_channel_get_name(session->channel));
 		return;
 	}

Modified: freeswitch/trunk/src/switch_cpp.cpp (15890 => 15891)


--- freeswitch/trunk/src/switch_cpp.cpp	2009-12-11 00:13:50 UTC (rev 15890)
+++ freeswitch/trunk/src/switch_cpp.cpp	2009-12-11 00:28:54 UTC (rev 15891)
@@ -569,7 +569,7 @@
 	sanity_check_noreturn;	
 	this->begin_allow_threads();
 	if (switch_channel_down(channel)) {
-		switch_core_session_hangup_state(session);
+		switch_core_session_hangup_state(session, SWITCH_FALSE);
 	}
 	this->end_allow_threads();
 }