Change in osmo-msc[master]: libmsc/gsm_09_11.c: implement guard timer for NCSS sessions

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Thu Feb 21 10:19:16 UTC 2019


Vadim Yanitskiy has submitted this change and it was merged. ( https://gerrit.osmocom.org/11992 )

Change subject: libmsc/gsm_09_11.c: implement guard timer for NCSS sessions
......................................................................

libmsc/gsm_09_11.c: implement guard timer for NCSS sessions

It may happen that either the MS or an EUSE would become
unresponsive during a call independent SS session, e.g.
due to a bug, or a dropped message. In such cases, the
corresponding transaction would remain unfreed forever.

This change introduces a guard timer, that prevents keeping
'stalled' NCSS sessions forever. As soon as it expires, both
sides (i.e. MS and EUSE) are getting notified, and the
transaction is being released.

By default, the timer expires after 30 seconds. As soon as
either the MS, or an EUSE initiates any activity,
the watchdog timer is rescheduled.

The timeout value can be configured from the VTY:

  msc
   ...
   ! Use 0 to disable this timer
   ncss guard-timeout 30

Please note that changing the timeout value at run-time
doesn't affect the existing NCSS sessions, excepting the
case when the timer is disabled at run-time.

This change makes TC_lu_and_ss_session_timeout pass.

Change-Id: Icf4d87c45e90324764073e8230e0fb9cb96dd9cb
Related Change-Id: (TTCN) I3e1791773d56617172ae27a46889a1ae4d400e2f
Related: OS#3655
---
M include/osmocom/msc/gsm_data.h
M include/osmocom/msc/transaction.h
M src/libmsc/gsm_09_11.c
M src/libmsc/msc_vty.c
M src/libmsc/osmo_msc.c
M tests/test_nodes.vty
6 files changed, 90 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved
  Vadim Yanitskiy: Looks good to me, but someone else must approve



diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index dab082d..7d3a1e7 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -192,6 +192,8 @@
 
 	/* Global MNCC guard timer value */
 	int mncc_guard_timeout;
+	/* Global guard timer value for NCSS sessions */
+	int ncss_guard_timeout;
 
 	struct {
 		struct mgcp_client_conf conf;
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
index 39b09ae..830328b 100644
--- a/include/osmocom/msc/transaction.h
+++ b/include/osmocom/msc/transaction.h
@@ -87,6 +87,8 @@
 			 * a subscriber after successful Paging Response
 			 */
 			struct msgb *msg;
+			/* Inactivity timer, triggers transaction release */
+			struct osmo_timer_list timer_guard;
 		} ss;
 	};
 
diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c
index d2ad0b7..c133656 100644
--- a/src/libmsc/gsm_09_11.c
+++ b/src/libmsc/gsm_09_11.c
@@ -51,6 +51,39 @@
 /* FIXME: choose a proper range */
 static uint32_t new_callref = 0x20000001;
 
+static void ncss_session_timeout_handler(void *_trans)
+{
+	struct gsm_trans *trans = (struct gsm_trans *) _trans;
+	struct osmo_gsup_message gsup_msg = { 0 };
+
+	/* The timeout might be disabled from the VTY */
+	if (trans->net->ncss_guard_timeout == 0)
+		return;
+
+	LOGP(DMM, LOGL_NOTICE, "SS/USSD session timeout, releasing "
+		"transaction (trans=%p, callref=%x)\n", trans, trans->callref);
+
+	/* Indicate connection release to subscriber (if active) */
+	if (trans->conn != NULL) {
+		/* This pair of cause location and value is used by commercial networks */
+		msc_send_ussd_release_complete_cause(trans->conn, trans->transaction_id,
+			GSM48_CAUSE_LOC_PUN_S_LU, GSM48_CC_CAUSE_NORMAL_UNSPEC);
+	}
+
+	/* Terminate GSUP session with EUSE */
+	gsup_msg.message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR;
+	OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi);
+
+	gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_END;
+	gsup_msg.session_id = trans->callref;
+	gsup_msg.cause = GMM_CAUSE_NET_FAIL;
+
+	osmo_gsup_client_enc_send(trans->net->vlr->gsup_client, &gsup_msg);
+
+	/* Finally, release this transaction */
+	trans_free(trans);
+}
+
 /* Entry point for call independent MO SS messages */
 int gsm0911_rcv_nc_ss(struct ran_conn *conn, struct msgb *msg)
 {
@@ -108,6 +141,10 @@
 			return -ENOMEM;
 		}
 
+		/* Init inactivity timer */
+		osmo_timer_setup(&trans->ss.timer_guard,
+			ncss_session_timeout_handler, trans);
+
 		/* Count active NC SS/USSD sessions */
 		osmo_counter_inc(conn->network->active_nc_ss);
 
@@ -116,6 +153,12 @@
 		cm_service_request_concludes(conn, msg);
 	}
 
+	/* (Re)schedule the inactivity timer */
+	if (conn->network->ncss_guard_timeout > 0) {
+		osmo_timer_schedule(&trans->ss.timer_guard,
+			conn->network->ncss_guard_timeout, 0);
+	}
+
 	/* Attempt to extract Facility IE */
 	rc = gsm0480_extract_ie_by_tag(gh, msgb_l3len(msg),
 		&facility_ie, &facility_ie_len, GSM0480_IE_FACILITY);
@@ -233,6 +276,12 @@
 		transt->conn = ran_conn_get(conn, RAN_CONN_USE_TRANS_NC_SS);
 		transt->paging_request = NULL;
 
+		/* (Re)schedule the inactivity timer */
+		if (conn->network->ncss_guard_timeout > 0) {
+			osmo_timer_schedule(&transt->ss.timer_guard,
+				conn->network->ncss_guard_timeout, 0);
+		}
+
 		/* Send stored message */
 		ss_msg = transt->ss.msg;
 		gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
@@ -317,6 +366,10 @@
 	}
 	trans->transaction_id = tid;
 
+	/* Init inactivity timer */
+	osmo_timer_setup(&trans->ss.timer_guard,
+		ncss_session_timeout_handler, trans);
+
 	/* Attempt to find connection */
 	conn = connection_for_subscr(vsub);
 	if (conn) {
@@ -371,6 +424,9 @@
 	if (trans->ss.msg != NULL)
 		msgb_free(trans->ss.msg);
 
+	/* Stop inactivity timer */
+	osmo_timer_del(&trans->ss.timer_guard);
+
 	/* One session less */
 	osmo_counter_dec(trans->net->active_nc_ss);
 }
@@ -420,6 +476,12 @@
 			return 0;
 	}
 
+	/* (Re)schedule the inactivity timer */
+	if (net->ncss_guard_timeout > 0) {
+		osmo_timer_schedule(&trans->ss.timer_guard,
+			net->ncss_guard_timeout, 0);
+	}
+
 	/* Allocate and prepare a new MT message */
 	ss_msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");
 	gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 078b83a..5aa533b 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -375,6 +375,18 @@
 		 "mncc-guard-timeout <0-255>",
 		 MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
 
+#define NCSS_STR "Configure call independent Supplementary Services\n"
+
+DEFUN(cfg_msc_ncss_guard_timeout,
+      cfg_msc_ncss_guard_timeout_cmd,
+      "ncss guard-timeout <0-255>",
+      NCSS_STR "Set guard timer for session activity\n"
+      "guard timer value (sec.), or 0 to disable\n")
+{
+	gsmnet->ncss_guard_timeout = atoi(argv[0]);
+	return CMD_SUCCESS;
+}
+
 DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
       "assign-tmsi",
       "Assign TMSI during Location Updating.\n")
@@ -496,6 +508,8 @@
 		vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
 	vty_out(vty, " mncc guard-timeout %i%s",
 		gsmnet->mncc_guard_timeout, VTY_NEWLINE);
+	vty_out(vty, " ncss guard-timeout %i%s",
+		gsmnet->ncss_guard_timeout, VTY_NEWLINE);
 	vty_out(vty, " %sassign-tmsi%s",
 		gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
 
@@ -1588,6 +1602,7 @@
 	install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
 	install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
 	install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
+	install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
 	install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
 	install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
 	install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c
index 9828da1..5c6f0aa 100644
--- a/src/libmsc/osmo_msc.c
+++ b/src/libmsc/osmo_msc.c
@@ -54,6 +54,7 @@
 	net->t3212 = 5;
 
 	net->mncc_guard_timeout = 180;
+	net->ncss_guard_timeout = 30;
 
 	net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
 
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index f2312d1..fb9e5f0 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -34,6 +34,7 @@
   mncc internal
   mncc external MNCC_SOCKET_PATH
   mncc guard-timeout <0-255>
+  ncss guard-timeout <0-255>
   no assign-tmsi
   auth-tuple-max-reuse-count <-1-2147483647>
   auth-tuple-reuse-on-error (0|1)
@@ -50,6 +51,12 @@
   mgw remote-port <0-65535>
 ...
 
+OsmoMSC(config-msc)# ncss?
+  ncss  Configure call independent Supplementary Services
+
+OsmoMSC(config-msc)# ncss ?
+  guard-timeout  Set guard timer for session activity
+
 OsmoMSC(config-msc)# mncc?
   mncc  Configure Mobile Network Call Control
 
@@ -123,6 +130,7 @@
  periodic location update 30
 msc
  mncc guard-timeout 180
+ ncss guard-timeout 30
  assign-tmsi
  cs7-instance-a 0
 ...

-- 
To view, visit https://gerrit.osmocom.org/11992
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Icf4d87c45e90324764073e8230e0fb9cb96dd9cb
Gerrit-Change-Number: 11992
Gerrit-PatchSet: 12
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Vadim Yanitskiy <axilirator at gmail.com>
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-CC: Stefan Sperling <stsp at stsp.name>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190221/d6b3dc48/attachment.htm>


More information about the gerrit-log mailing list