<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>