neels submitted this change.

View Change

Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved
fix SCCP conn leak on non-graceful HNB shutdown

Clean up SCCP connections when a HNB disconnects.

When a HNB disconnects, we clean up all RUA <-> SCCP connection state
for that HNB. In that cleanup, discarding the SCCP connection is so far
missing.

Add a flag indicating true between SCCP CC and DISCONNECT. Hence we can
tell during context_map_deactivate() whether the cleanup is graceful
(DISCONNECT already sent) or non-graceful (need to DISCONNECT).

Change-Id: Icc2db9f6c0b2d0a814ff1110ffbe5e8f7f629222
---
M include/osmocom/hnbgw/context_map.h
M src/osmo-hnbgw/context_map.c
M src/osmo-hnbgw/hnbgw_cn.c
M src/osmo-hnbgw/hnbgw_rua.c
4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h
index 99efe8a..fe09da0 100644
--- a/include/osmocom/hnbgw/context_map.h
+++ b/include/osmocom/hnbgw/context_map.h
@@ -43,6 +43,10 @@
bool is_ps;
/* SCCP User SAP connection ID */
uint32_t scu_conn_id;
+ /* Set to true on SCCP Conn Conf, set to false when an OSMO_SCU_PRIM_N_DISCONNECT has been sent for the SCCP
+ * User SAP conn. Useful to avoid leaking SCCP connections: guarantee that an OSMO_SCU_PRIM_N_DISCONNECT gets
+ * sent, even when RUA fails to gracefully disconnect. */
+ bool scu_conn_active;
/* Pending data to be sent: when we send an "empty" SCCP CR first, the initial RANAP message will be sent in a
* separate DT once the CR is confirmed. This caches the initial RANAP message. */
struct msgb *cached_msg;
diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c
index 98dffad..31ba032 100644
--- a/src/osmo-hnbgw/context_map.c
+++ b/src/osmo-hnbgw/context_map.c
@@ -26,6 +26,8 @@

#include <osmocom/core/timer.h>

+#include <osmocom/sigtran/sccp_helpers.h>
+
#include <osmocom/hnbgw/hnbgw.h>
#include <osmocom/hnbgw/hnbgw_rua.h>
#include <osmocom/hnbgw/context_map.h>
@@ -174,6 +176,12 @@
if (map->state != MAP_S_RESERVED2)
map->state = MAP_S_RESERVED1;

+ /* Is SCCP still active and needs to be disconnected ungracefully? */
+ if (map->scu_conn_active) {
+ osmo_sccp_tx_disconn(map->hnb_ctx->gw->sccp.cnlink->sccp_user, map->scu_conn_id, NULL, 0);
+ map->scu_conn_active = false;
+ }
+
/* a possibly still existing MGW FSM must be terminated when the context
* map is deactivated. (this is a cornercase) */
if (map->mgw_fi) {
diff --git a/src/osmo-hnbgw/hnbgw_cn.c b/src/osmo-hnbgw/hnbgw_cn.c
index 7cbfcec..c4189e8 100644
--- a/src/osmo-hnbgw/hnbgw_cn.c
+++ b/src/osmo-hnbgw/hnbgw_cn.c
@@ -337,6 +337,8 @@
struct osmo_prim_hdr *oph)
{
struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(cnlink->gw->sccp.client);
+ struct hnbgw_context_map *map;
+
LOGP(DMAIN, LOGL_DEBUG, "handle_cn_conn_conf() conn_id=%d, addrs: called=%s calling=%s responding=%s\n",
param->conn_id,
osmo_sccp_addr_to_str_c(OTC_SELECT, ss7, &param->called_addr),
@@ -346,9 +348,17 @@
/* Nothing needs to happen for RUA, RUA towards the HNB doesn't seem to know any confirmations to its CONNECT
* operation. */

+ map = context_map_by_cn(cnlink, param->conn_id);
+ if (!map)
+ return 0;
+
+ /* SCCP connection is confirmed. Mark conn as active, i.e. requires a DISCONNECT to clean up the SCCP
+ * connection. */
+ map->scu_conn_active = true;
+
/* If our initial SCCP CR was sent without data payload, then the initial RANAP message is cached and waiting to
* be sent as soon as the SCCP connection is confirmed. See if that is the case, send cached data. */
- context_map_send_cached_msg(context_map_by_cn(cnlink, param->conn_id));
+ context_map_send_cached_msg(map);

return 0;
}
diff --git a/src/osmo-hnbgw/hnbgw_rua.c b/src/osmo-hnbgw/hnbgw_rua.c
index f4e24d7..215379a 100644
--- a/src/osmo-hnbgw/hnbgw_rua.c
+++ b/src/osmo-hnbgw/hnbgw_rua.c
@@ -252,6 +252,9 @@
prim->u.disconnect.conn_id = map->scu_conn_id;
prim->u.disconnect.cause = cause;
release_context_map = true;
+ /* Mark SCCP conn as gracefully disconnected */
+ if (map)
+ map->scu_conn_active = false;
break;
case OSMO_SCU_PRIM_N_UNITDATA:
prim->u.unitdata.called_addr = *remote_addr;

To view, visit change 31028. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmo-hnbgw
Gerrit-Branch: master
Gerrit-Change-Id: Icc2db9f6c0b2d0a814ff1110ffbe5e8f7f629222
Gerrit-Change-Number: 31028
Gerrit-PatchSet: 2
Gerrit-Owner: neels <nhofmeyr@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged