<p>Vadim Yanitskiy has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/11992">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">libmsc/gsm_09_11.c: implement guard timer for SS sessions<br><br>It may happen that either the MS or an ESME would become unresponsive,<br>e.g. due to a bug, or dropped message. In such cases, the<br>corresponding transaction will remain unfreed forever.<br><br>This change introduces a guard timer, that prevents keeping<br>'stalled' SS sessions forever. As soon as it expires, both<br>sides (i.e. MS and ESME) are getting notified, and the<br>transaction is being released.<br><br>By default, the timer expires after 255 seconds. As soon as<br>either the MS, or an ESME initiates any activity, the timer<br>is being rescheduled.<br><br>The timer can be configured from the VTY:<br><br> msc<br> ss-guard-timeout 255<br><br>or disabled by setting 0.<br><br>Change-Id: Icf4d87c45e90324764073e8230e0fb9cb96dd9cb<br>Related Change-Id: (TTCN) I3e1791773d56617172ae27a46889a1ae4d400e2f<br>Related: OS#3655<br>---<br>M include/osmocom/msc/gsm_data.h<br>M include/osmocom/msc/transaction.h<br>M src/libmsc/gsm_09_11.c<br>M src/libmsc/msc_vty.c<br>M src/libmsc/osmo_msc.c<br>5 files changed, 75 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/92/11992/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h</span><br><span>index 085248c..4e338c0 100644</span><br><span>--- a/include/osmocom/msc/gsm_data.h</span><br><span>+++ b/include/osmocom/msc/gsm_data.h</span><br><span>@@ -338,6 +338,8 @@</span><br><span> </span><br><span> /* Global MNCC guard timer value */</span><br><span> int mncc_guard_timeout;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* SS session guard timer value */</span><br><span style="color: hsl(120, 100%, 40%);">+ int ss_guard_timeout;</span><br><span> </span><br><span> struct {</span><br><span> struct mgcp_client_conf conf;</span><br><span>diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h</span><br><span>index b7d7971..05fcba1 100644</span><br><span>--- a/include/osmocom/msc/transaction.h</span><br><span>+++ b/include/osmocom/msc/transaction.h</span><br><span>@@ -84,6 +84,8 @@</span><br><span> * a subscriber after successful Paging Response</span><br><span> */</span><br><span> struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Time-out of inactivity when we will delete the session */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_timer_list timeout;</span><br><span> } ss;</span><br><span> };</span><br><span> </span><br><span>diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c</span><br><span>index b863ce8..34c7248 100644</span><br><span>--- a/src/libmsc/gsm_09_11.c</span><br><span>+++ b/src/libmsc/gsm_09_11.c</span><br><span>@@ -52,6 +52,36 @@</span><br><span> /* FIXME: choose a proper range */</span><br><span> static uint32_t new_callref = 0x20000001;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* SS/USSD session time-out handler */</span><br><span style="color: hsl(120, 100%, 40%);">+static void ss_session_timeout(void *_trans)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_trans *trans = (struct gsm_trans *) _trans;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_gsup_message gsup_msg = { 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMM, LOGL_NOTICE, "SS/USSD session (trans=%p, callref=%x) "</span><br><span style="color: hsl(120, 100%, 40%);">+ "timeout, destroying\n", trans, trans->callref);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Release connection (if any) with subscriber */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (trans->conn != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ msc_send_ussd_release_complete(trans->conn,</span><br><span style="color: hsl(120, 100%, 40%);">+ trans->transaction_id); /* TODO: specify some cause! */</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Notify EUSE (i.e. terminate GSUP session)</span><br><span style="color: hsl(120, 100%, 40%);">+ * FIXME: use a proper cause value */</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup_msg.message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup_msg.session_id = trans->callref;</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup_msg.cause = GMM_CAUSE_NET_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_msg_enc_send(trans->net->vlr->gsup_client, &gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Finally, release this transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+ trans_free(trans);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Entry point for call independent MO SS messages */</span><br><span> int gsm0911_rcv_nc_ss(struct gsm_subscriber_connection *conn, struct msgb *msg)</span><br><span> {</span><br><span>@@ -110,6 +140,9 @@</span><br><span> return -ENOMEM;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Init self-destruction timer */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_setup(&trans->ss.timeout, ss_session_timeout, trans);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Count active NC SS/USSD sessions */</span><br><span> osmo_counter_inc(conn->network->active_nc_ss);</span><br><span> </span><br><span>@@ -118,6 +151,12 @@</span><br><span> cm_service_request_concludes(conn, msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* (Re)schedule self-destruction timer */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conn->network->ss_guard_timeout > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_schedule(&trans->ss.timeout,</span><br><span style="color: hsl(120, 100%, 40%);">+ conn->network->ss_guard_timeout, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Attempt to extract Facility IE */</span><br><span> rc = gsm0480_extract_ie_by_tag(gh, msgb_l3len(msg),</span><br><span> &facility_ie, &facility_ie_len, GSM0480_IE_FACILITY);</span><br><span>@@ -235,6 +274,12 @@</span><br><span> transt->conn = msc_subscr_conn_get(conn, MSC_CONN_USE_TRANS_NC_SS);</span><br><span> transt->paging_request = NULL;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* (Re)schedule self-destruction timer */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conn->network->ss_guard_timeout > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_schedule(&transt->ss.timeout,</span><br><span style="color: hsl(120, 100%, 40%);">+ conn->network->ss_guard_timeout, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Send stored message */</span><br><span> ss_msg = transt->ss.msg;</span><br><span> OSMO_ASSERT(ss_msg);</span><br><span>@@ -322,6 +367,9 @@</span><br><span> }</span><br><span> trans->transaction_id = tid;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Init inactivity watchdog */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_setup(&trans->ss.timeout, ss_session_timeout, trans);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Attempt to find connection */</span><br><span> conn = connection_for_subscr(vsub);</span><br><span> if (conn) {</span><br><span>@@ -375,6 +423,9 @@</span><br><span> if (trans->ss.msg != NULL)</span><br><span> msgb_free(trans->ss.msg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Stop self-destruction time-out */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_del(&trans->ss.timeout);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* One session less */</span><br><span> osmo_counter_dec(trans->net->active_nc_ss);</span><br><span> }</span><br><span>@@ -424,6 +475,12 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* (Re)schedule self-destruction timer */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (net->ss_guard_timeout > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_schedule(&trans->ss.timeout,</span><br><span style="color: hsl(120, 100%, 40%);">+ net->ss_guard_timeout, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Allocate and prepare a new MT message */</span><br><span> ss_msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");</span><br><span> gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));</span><br><span>diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c</span><br><span>index 245a227..c9abe1c 100644</span><br><span>--- a/src/libmsc/msc_vty.c</span><br><span>+++ b/src/libmsc/msc_vty.c</span><br><span>@@ -346,6 +346,16 @@</span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_msc_ss_guard_timeout,</span><br><span style="color: hsl(120, 100%, 40%);">+ cfg_msc_ss_guard_timeout_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "ss-guard-timeout <0-255>",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Set guard timer for SS/USSD session activity\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "guard timer value (sec.), or 0 to disable")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ gsmnet->ss_guard_timeout = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,</span><br><span> "assign-tmsi",</span><br><span> "Assign TMSI during Location Updating.\n")</span><br><span>@@ -436,6 +446,8 @@</span><br><span> vty_out(vty, "msc%s", VTY_NEWLINE);</span><br><span> vty_out(vty, " mncc-guard-timeout %i%s",</span><br><span> gsmnet->mncc_guard_timeout, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " ss-guard-timeout %i%s",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsmnet->ss_guard_timeout, VTY_NEWLINE);</span><br><span> vty_out(vty, " %sassign-tmsi%s",</span><br><span> gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);</span><br><span> </span><br><span>@@ -1448,6 +1460,7 @@</span><br><span> install_node(&msc_node, config_write_msc);</span><br><span> install_element(MSC_NODE, &cfg_msc_assign_tmsi_cmd);</span><br><span> install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(MSC_NODE, &cfg_msc_ss_guard_timeout_cmd);</span><br><span> install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);</span><br><span> install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);</span><br><span> install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);</span><br><span>diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c</span><br><span>index f2c84e6..bd9e96f 100644</span><br><span>--- a/src/libmsc/osmo_msc.c</span><br><span>+++ b/src/libmsc/osmo_msc.c</span><br><span>@@ -55,6 +55,7 @@</span><br><span> net->t3212 = 5;</span><br><span> </span><br><span> net->mncc_guard_timeout = 180;</span><br><span style="color: hsl(120, 100%, 40%);">+ net->ss_guard_timeout = 255;</span><br><span> </span><br><span> net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11992">change 11992</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/11992"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-msc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Icf4d87c45e90324764073e8230e0fb9cb96dd9cb </div>
<div style="display:none"> Gerrit-Change-Number: 11992 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>